Please help! char* problems!

Discussion in 'C Programming' started by Sona, Sep 11, 2003.

  1. Sona

    Sona Guest

    I understand the problem I'm having but am not sure how to fix it. My
    code passes two char* to a function which reads in some strings from a
    file and copies the contents into the two char*s. Now when my function
    returns, the values stored in the char* are some garbage values (perhaps
    because I didn't allocate any memory for them).. but even if I allocate
    memory in the function, on the return of this function I see garbage..
    here is my code:


    typedef char* string;

    int main(int argc, char* argv[]) {

    parseFile(argv[1], strX, strY);
    ...
    ... // values of strX and strY are garbage

    }

    void parseFile(const string file, string source, string target){

    //read in some stuff from the file

    source = malloc((size_t)sizeof(char)*X_SIZE_READ_FROM_FILE);
    target = malloc((size_t)sizeof(char)*Y_SIZE_READ_FROM_FILE);

    strcpy(source, STRING_READ_FROM_FILE);
    strcpy(target, STRING_READ_FROM_FILE);

    // print source and target... they're correct

    }


    can someone tell me what to do?

    Thanks


    Sona
     
    Sona, Sep 11, 2003
    #1
    1. Advertising

  2. Sona <> wrote in
    news:3f606d28$:

    > I understand the problem I'm having but am not sure how to fix it. My
    > code passes two char* to a function which reads in some strings from a
    > file and copies the contents into the two char*s. Now when my function
    > returns, the values stored in the char* are some garbage values (perhaps
    > because I didn't allocate any memory for them).. but even if I allocate
    > memory in the function, on the return of this function I see garbage..
    > here is my code:
    >
    >
    > typedef char* string;


    First, typedef abuse like this should be avoided. You need to be
    comfortable with pointers if you are going to be a C programmer. Besides,
    char * does not mean you have a C string since you can have a pointer to a
    bunch of 8-bit values without a null char.

    >
    > int main(int argc, char* argv[]) {
    >
    > parseFile(argv[1], strX, strY);
    > ..
    > .. // values of strX and strY are garbage
    >
    > }
    >
    > void parseFile(const string file, string source, string target){
    >
    > //read in some stuff from the file
    >
    > source = malloc((size_t)sizeof(char)*X_SIZE_READ_FROM_FILE);
    > target = malloc((size_t)sizeof(char)*Y_SIZE_READ_FROM_FILE);
    >
    > strcpy(source, STRING_READ_FROM_FILE);
    > strcpy(target, STRING_READ_FROM_FILE);
    >
    > // print source and target... they're correct
    >
    > }


    Try this:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>

    #define STRING_READ_FROM_FILE_X "Hello from X file"
    #define STRING_READ_FROM_FILE_Y "Good-bye from Y file"
    #define X_SIZE_READ_FROM_FILE sizeof (STRING_READ_FROM_FILE_X)
    #define Y_SIZE_READ_FROM_FILE sizeof (STRING_READ_FROM_FILE_Y)

    /* Function correctly takes pointer to pointer to char, not pointer to
    char ** since we need to modify the pointer and then what it points to.
    */
    int parseFile(const char *pFile, char **pSrc, char **pTgt)
    {
    int failures = !0;

    /* Set up so we can free() unconditionally on error.
    */
    *pSrc = NULL;
    *pTgt = NULL;

    /* read in some stuff from the file since sizeof (char) is
    ** gauaranteed to be one, we don't include it in the malloc call.
    */
    *pSrc = malloc(X_SIZE_READ_FROM_FILE);
    *pTgt = malloc(Y_SIZE_READ_FROM_FILE);

    if (*pSrc && *pTgt)
    {
    strcpy(*pSrc, STRING_READ_FROM_FILE_X);
    strcpy(*pTgt, STRING_READ_FROM_FILE_Y);
    failures = 0;

    /* print source and target... they're correct
    */
    }
    else
    {
    free(*pSrc);
    free(*pTgt);
    }

    return failures;
    }

    /* main()
    */
    int main(int argc, char *argv[])
    {
    char *pStrX;
    char *pStrY;

    /* Pass pointers to pointers since you wish to change what
    ** address they point to.
    */
    if (!parseFile(argv[1], &pStrX, &pStrY))
    {
    /* values of strX and strY are garbage
    */

    /* All done with pointers' memory blocks.
    */
    free(pStrX);
    free(pStrY);
    }

    return 0;
    }



    --
    - Mark ->
    --
     
    Mark A. Odell, Sep 11, 2003
    #2
    1. Advertising

  3. Sona

    Al Bowers Guest

    Sona wrote:
    > I understand the problem I'm having but am not sure how to fix it. My
    > code passes two char* to a function which reads in some strings from a
    > file and copies the contents into the two char*s. Now when my function
    > returns, the values stored in the char* are some garbage values (perhaps
    > because I didn't allocate any memory for them).. but even if I allocate
    > memory in the function, on the return of this function I see garbage..
    > here is my code:
    >
    >
    > typedef char* string;
    >
    > int main(int argc, char* argv[]) {
    >
    > parseFile(argv[1], strX, strY);
    > ..
    > .. // values of strX and strY are garbage
    >
    > }
    >
    > void parseFile(const string file, string source, string target){
    >
    > //read in some stuff from the file
    >
    > source = malloc((size_t)sizeof(char)*X_SIZE_READ_FROM_FILE);
    > target = malloc((size_t)sizeof(char)*Y_SIZE_READ_FROM_FILE);
    >
    > strcpy(source, STRING_READ_FROM_FILE);
    > strcpy(target, STRING_READ_FROM_FILE);
    >
    > // print source and target... they're correct
    >
    > }
    >
    >
    > can someone tell me what to do?
    >


    You have declared strX and strY in function main. Since they are
    not initialized, they may point to what you call garbage.
    When you call function parseFile a copy the value of strX is
    assigned to variable source and a copy of strY is made to the variable
    target. You then change the values of target and source when you
    assign them the return of function malloc. Then strcpy. All is ok in the
    function and it prints the strings fine. But the variables in main
    are not changed, thus the variables source and target point to the
    allocated space. strX and strY still have garbage values.

    A solution is to redefine the function parseFile so it will accept
    the address of strX and strY.
    Something similiar to this:
    string parseFile(const string file, string *source, string *target);
    and the call in main will be:
    parseFile("const string", &strX, &strY);

    An Example:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    #define SIZE_READ_FROM_FILE 128

    typedef char *string;

    string parseFile(const string file, string *source, string *target)
    {
    if(strlen(file) > SIZE_READ_FROM_FILE-1) return NULL;
    if((*source = malloc(SIZE_READ_FROM_FILE)) == NULL) return NULL;
    if((*target = malloc(SIZE_READ_FROM_FILE)) == NULL)
    {
    free(*source);
    return NULL;
    }
    strcpy(*source, file);
    strcpy(*target, file);
    return *source;
    }

    int main(void)
    {
    string strX, strY;

    if(parseFile("This is a test",&strX,&strY))
    {
    printf("strX = \"%s\"\nstrY = \"%s\"\n",strX,strY);
    free(strX);
    free(strY);
    }
    else puts("Failure in parseFile function");
    return 0;
    }
    --
    Al Bowers
    Tampa, Fl USA
    mailto: (remove the x)
    http://www.geocities.com/abowers822/
     
    Al Bowers, Sep 11, 2003
    #3
  4. Sona

    Tom Zych Guest

    "Mark A. Odell" wrote:

    [snip]
    > /* Set up so we can free() unconditionally on error.
    > */
    > *pSrc = NULL;
    > *pTgt = NULL;

    [snip]
    > *pSrc = malloc(X_SIZE_READ_FROM_FILE);
    > *pTgt = malloc(Y_SIZE_READ_FROM_FILE);
    >
    > if (*pSrc && *pTgt)
    > {

    [snip]
    > }
    > else
    > {
    > free(*pSrc);
    > free(*pTgt);
    > }


    I don't see why it's necessary to initialize them to NULL. Doesn't
    malloc return NULL on failure anyway? Is it just a good habit? I can
    see it would be useful in cases where you might return before some
    of the mallocs.

    --
    Tom Zych
    This email address will expire at some point to thwart spammers.
    Permanent address: echo '' | rot13
     
    Tom Zych, Sep 11, 2003
    #4
  5. Tom Zych <> wrote in news::

    > "Mark A. Odell" wrote:
    >
    > [snip]
    >> /* Set up so we can free() unconditionally on error.
    >> */
    >> *pSrc = NULL;
    >> *pTgt = NULL;

    > [snip]
    >> *pSrc = malloc(X_SIZE_READ_FROM_FILE);
    >> *pTgt = malloc(Y_SIZE_READ_FROM_FILE);
    >>
    >> if (*pSrc && *pTgt)
    >> {

    > [snip]
    >> }
    >> else
    >> {
    >> free(*pSrc);
    >> free(*pTgt);
    >> }

    >
    > I don't see why it's necessary to initialize them to NULL.


    It's not, the way I did it. I intended to bail if the first malloc failed
    but forgot. You are correct, of course.

    --
    - Mark ->
    --
     
    Mark A. Odell, Sep 11, 2003
    #5
  6. Groovy hepcat Sona was jivin' on Thu, 11 Sep 2003 22:49:08 +1000 in
    comp.lang.c.
    Please help! char* problems!'s a cool scene! Dig it!

    >I understand the problem I'm having but am not sure how to fix it. My
    >code passes two char* to a function which reads in some strings from a
    >file and copies the contents into the two char*s. Now when my function
    >returns, the values stored in the char* are some garbage values (perhaps
    >because I didn't allocate any memory for them).. but even if I allocate
    >memory in the function, on the return of this function I see garbage..


    This is a FAQ. Please go to
    http://www.eskimo.com/~scs/C-faq/top.html and read it. Your question
    (or part of it) is FAQ 4.8.

    --

    Dig the even newer still, yet more improved, sig!

    http://alphalink.com.au/~phaywood/
    "Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
    I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
     
    Peter Shaggy Haywood, Sep 15, 2003
    #6
  7. I think you're having the same problem that I had, please refer to post
    (very recent) with subject: return address of new memory.
    It would be better if you posted your code, I'm doing something similar in
    my programs, so first I give you that stuff and later I will simply paste
    other people's stuff here:
    main():
    char *grayhistmatchfile = NULL;
    char *ihsfile = NULL;
    char *ihistmatchfile = NULL;
    char *pcfile = NULL;
    char *pcmtxfile = NULL;
    char *inversepcfile = NULL;
    char *graydwtfile = NULL;

    ewrm_generateFileNames(&grayhistmatchfile, &ihsfile, &pcfile, &pcmtxfile,
    &ihistmatchfile,
    &graydwt1file, &graydwt2file, &graydwt3file, &resampledifile,
    &copya1file, &copya2file, &copya3file,
    &mergedihvdfile, &idwt1file, &idwt2file, &idwt3file,
    &mergedidwt1file, &mergedidwt2file, &mergedihmfile, &hsresampledfile,
    &rgbfile, &pc_xresampledfile, &inversepcfile, &stackoutput,
    &lclerr);

    void ewrm_generateFileNames(char **grayhistmatchfile, char **ihsfile, char
    **pcfile, char **pcmtxfile, char **ihistmatchfile,
    char **graydwt1file, char **graydwt2file, char **graydwt3file, char
    **resampledifile,
    char **copya1file, char **copya2file, char **copya3file,
    char **mergedihvdfile, char **idwt1file, char **idwt2file, char
    **idwt3file,
    char **mergedidwt1file, char **mergedidwt2file, char **mergedihmfile, char
    **hsresampledfile,
    char **rgbfile, char **pc_xresampledfile, char **inversepcfile, char
    **stackoutput,
    Eerr_ErrorReport **inerr)
    {

    You copy to char * in this function, e.g.
    *graydwt1file = strcpy(...);

    }

    *****************************************************
    You are getting confused with levels of indirection. A good rule of
    thumb: if you find yourself assigning something to a function parameter
    (not to what the parameter points at), then you're on the wrong track.

    > void getWaveletCoeffs(float *ld, float *hd, int *filterLen)


    Change this to:
    void getWaveletCoeffs(float **ld, float **hd, int *filterLen)

    Why? Because you wish to assign to *pointers* in main(). Therefore
    this function needs to receive *pointers to pointers*.
    If you wish to assign to "foo type", then your function must receive
    "pointers to foo type". This goes for any meaning of "foo type".

    > {
    > ld = (float*)malloc(2*SZFLOAT);
    > hd = (float*)malloc(2*SZFLOAT);


    Change these to:
    *ld = malloc(2*SZFLOAT);
    *hd = malloc(2*SZFLOAT);

    Note that while your old code assigns to ld and hd themselves, mine
    assigns to what they point at. (See the * operator?) This is what I
    was talking about earlier.

    > *ld++ = 0.7071;
    > *ld-- = 0.7071;


    > *hd++ = -0.7071;
    > *hd-- = 0.7071;


    These also need to be changed, to something like:
    **ld = 0.7071;
    *(*ld+1) = 0.7071;
    **hd = -0.7071;
    *(*hd+1) = 0.7071;
    If I understood your logic correctly.



    --
    Pushkar Pradhan
    "Peter "Shaggy" Haywood" <> wrote in
    message news:...
    > Groovy hepcat Sona was jivin' on Thu, 11 Sep 2003 22:49:08 +1000 in
    > comp.lang.c.
    > Please help! char* problems!'s a cool scene! Dig it!
    >
    > >I understand the problem I'm having but am not sure how to fix it. My
    > >code passes two char* to a function which reads in some strings from a
    > >file and copies the contents into the two char*s. Now when my function
    > >returns, the values stored in the char* are some garbage values (perhaps
    > >because I didn't allocate any memory for them).. but even if I allocate
    > >memory in the function, on the return of this function I see garbage..

    >
    > This is a FAQ. Please go to
    > http://www.eskimo.com/~scs/C-faq/top.html and read it. Your question
    > (or part of it) is FAQ 4.8.
    >
    > --
    >
    > Dig the even newer still, yet more improved, sig!
    >
    > http://alphalink.com.au/~phaywood/
    > "Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry &

    W. Walker.
    > I know it's not "technically correct" English; but since when was rock &

    roll "technically correct"?
     
    Pushker Pradhan, Sep 15, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. KK
    Replies:
    2
    Views:
    646
    Big Brian
    Oct 14, 2003
  2. wwj
    Replies:
    7
    Views:
    576
  3. wwj
    Replies:
    24
    Views:
    2,546
    Mike Wahler
    Nov 7, 2003
  4. Ben Pfaff
    Replies:
    5
    Views:
    490
    Tristan Miller
    Jan 17, 2004
  5. lovecreatesbeauty
    Replies:
    1
    Views:
    1,097
    Ian Collins
    May 9, 2006
Loading...

Share This Page