Please help! char* problems!

S

Sona

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
 
M

Mark A. Odell

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;
}
 
A

Al Bowers

Sona said:
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;
}
 
T

Tom Zych

:

[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.
 
M

Mark A. Odell

Tom Zych said:
:

[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.
 
P

Peter Shaggy Haywood

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"?
 
P

Pushker Pradhan

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 said:
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!


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"?
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top