Thread: error while call function that returns a string to a structure

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    37

    error while call function that returns a string to a structure

    I am a beginner to C programming. I have done a few programs here and there and am also following the book 'The C programming language' by K&R.


    The program consists of 2 parts: the main and 1 function.

    Function is initialised as follows:

    Code:
     
    
    char genCallNR();
    this function char genCallNr() puts into a string the current date e.g 0120609


    the string that holds this date is defined:

    Code:
    char callnr[11];
    
    return callnr[0]; //trying to return this string to the main function
    the structure is defined as:

    Code:
    typedef struct call{
    int d;
    int qty;
    char con[100], owner[100];
    char* callnr;
    } CALL;

    I try to put the return value from the genCallNr function into char* callnr:

    Code:
    CALL c;
    c.callnr = genCallNr();
    when I try to execute the program I get a stack smashing error.

    also, I get some compile warnings.

    Anyyone can explain to me what I am doing wrong?

    PS I couldnt copy the errors from VM ware to thisd computer, many appologies

    Update: The only compile error I get is - "warning: assignment makes pointer from ineger without cast"

    and the offending line is:

    Code:
    c.callnr = genCallNr();
    Last edited by Tom Bombadil; 05-19-2009 at 07:02 AM.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    If you want to assign to a pointer, return a pointer. The prototype should look like this:
    Code:
    char *genCallNR();
    And -- important! -- the return value in the function should not include an array subscript[0].
    Code:
    return callnr;
    However, there will be a problem because as is, callnr is a stack variable local to genCallNR(). Which means the memory allocated to it is no longer protected after the function call ends and returns a pointer.
    So you must manually allocate "heap" memory to a variable if you wish to use it as a return value with an indefinite lifespan:
    Code:
    #include <stdlib.h>  /* this library has malloc() and free() */
    char genCallNR() {
         char *callnr = malloc(11);  /* EDIT corrected silly mistake */
    When you are done using the string (ie, after the last time it is referenced in the program), you should "deallocate" this heap memory (ie, release it for some other use) since your computer does not have an infinite memory:
    Code:
    free(c.callnr);
    Last edited by MK27; 05-19-2009 at 07:51 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Mar 2009
    Posts
    37
    Thank you MK27

    I corrected the things that you pointed out. However things don't run smoothly.
    I managed to get the code from the VMware:

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>
    #include<string.h>
    
    char *genCallNr();
    
    typedef struct call
    {
    
       int date1;
       int qty;
       char contract[100], owner[100], partnr[100];
       char* callnr;
    } CALL;
    
    int main(void)
    {
     CALL c;
     strcpy(c.contract, "DELL");
     strcpy(c.owner, "EMEA");
     strcpy(c.partnr, "615TW");
     c.callnr = genCallNr();
    
    printf("%s\t%s\t%s\t%s", c.contract, c.owner, c.partnr, c.callnr);
    free (c.callnr);
    
    }
    
    char *genCallNr(){
    char callnr = malloc(11);
    time_t now;
     struct tm *ts;
     char buf[80];
     //char callnr[11];
    
     now = time(NULL);
     ts = localtime(&now);
    
     strftime(buf, sizeof(buf), "1%y%m%d%H%m", ts);
     printf("\n%s", buf);
     strncpy(callnr, buf,80);
     printf("\n%s", callnr);
    return callnr;
    }
    I get segmentation fault. Any idea why ?
    Last edited by Tom Bombadil; 05-19-2009 at 07:39 AM.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    char *genCallNr(){
    char callnr = malloc(11);
    time_t now;
     struct tm *ts;
     char buf[80];
     //char callnr[11];
    
     now = time(NULL);
     ts = localtime(&now);
    
     strftime(buf, sizeof(buf), "1%y%m%d%H%m", ts);
     printf("\n%s", buf);
     strncpy(callnr, buf,80);
     printf("\n%s", callnr);
    return callnr;
    }
    See anything wrong here?

    The string you produce is like this:
    "10905191405" - which is exactly 11 digits long, but you also need space for the zero to terminate string.

    And I actually expect that you want %M at the end of your strftime string - or are you obfuscating it by putting the month in twice?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Tom Bombadil
    I get segmentation fault. Any idea why ?
    Just as Tom Bombadil was likely to misplace the One Ring, you appear to have misplaced the One Asterisk that makes the difference between callnr being a char instead of a pointer to char.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Yes, if you malloc() 11 bytes, do not use more than 11 bytes! Or else malloc more to start with. And remember, a string in C *must* be null terminated (the sting functions such as strcpy do this automatically), which requires one "extra" byte at the end.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by laserlight View Post
    Just as Tom Bombadil was likely to misplace the One Ring, you appear to have misplaced the One Asterisk that makes the difference between callnr being a char instead of a pointer to char.
    AND THAT WAS MY FAULT!

    Sorry Tom, still brewing the coffee I will go back and correct my post but that should have been:
    Code:
    char *callnr = malloc(12)
    I think your compiler will have complained right away...
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    Registered User
    Join Date
    Mar 2009
    Posts
    37
    Thanks matsp:

    Code:
    char *genCallNr(){
    char callnr = malloc(12);
    time_t now;
     struct tm *ts;
     char buf[12];
     //char callnr[11];
    
     now = time(NULL);
     ts = localtime(&now);
    
     strftime(buf, sizeof(buf), "1%y%m%d%H%M", ts);
     printf("\n%s", buf);
     strncpy(callnr, buf,12);
     printf("\n%s", callnr);
    return callnr;
    }
    i thought the %m was minutes :-S.

    Compiling the code I get:

    Code:
    qa@qa:~/Programming$ gcc -o struct_calls struct_calls.c 
    struct_calls.c: In function \u2018genCallNr\u2019:
    struct_calls.c:31: warning: initialization makes integer from pointer without a cast
    struct_calls.c:42: warning: passing argument 1 of \u2018strncpy\u2019 makes pointer from integer without a cast
    struct_calls.c:44: warning: return makes pointer from integer without a cast
    and the the output is the following:

    Segmentation fault

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by MK27
    AND THAT WAS MY FAULT!
    Will the real Tom Bombadil please stand up?

    By the way, Tom Bombadil, please indent your code better. It makes it easier to read and spot errors.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Mar 2009
    Posts
    37
    Quote Originally Posted by laserlight View Post
    Just as Tom Bombadil was likely to misplace the One Ring, you appear to have misplaced the One Asterisk that makes the difference between callnr being a char instead of a pointer to char.
    Thanks everyone, got it working now. Didn't see all the other replies posted before my last post!

    Much appreciated

    And i will try to indent my C code better too. Enjoy the rest of the day!
    Last edited by Tom Bombadil; 05-19-2009 at 08:01 AM.

  11. #11
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    your problem is right here:

    Code:
    char callnr = malloc(12);
    should be:
    Code:
    char *callnr = malloc(12);
    hope this helps.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I think you had better learn more about pointers, since it seems kind of obvious you don't know what you're doing...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help calling function is asm
    By brietje698 in forum C++ Programming
    Replies: 24
    Last Post: 12-06-2007, 04:48 PM
  2. String issues
    By The_professor in forum C++ Programming
    Replies: 7
    Last Post: 06-12-2007, 09:11 AM
  3. Replies: 5
    Last Post: 02-14-2006, 09:04 AM
  4. Call a function from a string?
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 08-06-2002, 04:38 PM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM