Reputation: 1652
I have read all question for this type of problem but I can't fix mine. The problem is that I use a function for reading data from a file and I get this error: "Stack around variable 'p' was corrupted" This is the function
Firm readFirm(char* name)
{
FILE* file = NULL;
int i = 0;
Firm firm;
char line[100];
char* p[5] = {(char*)malloc(50)};
char tmp[50];
strcpy(tmp,name);
strcat(tmp,".txt");
file = fopen(tmp,"rb");
getline(file,line,100);
strcpy(firm.name,line);
getline(file,line,100);
strcpy(firm.EIK,line);
getline(file,line,100);
split(p,line," ");
for (i = 0 ; p[i] != NULL; i++)
firm.price[i] = atoi(p[i]);
getline(file,line,100);
split(p,line,".");
firm.day = atoi(p[0]);
firm.month = atoi(p[1]);
firm.year = atoi(p[2]);
fclose(file);
return firm;
}
Please help because I don't know how to fix it!
This is the split function:
char ** split( char *result[], char *w, const char *delim)
{
int i=0;
char *p=NULL;
for(i=0, result[0]=NULL, p=strtok(w, delim); p!=NULL; p=strtok(NULL, delim), i++ )
{
result[i]=p;
result[i+1]=NULL;
}
return result;
}
Upvotes: 0
Views: 1152
Reputation: 61900
change the line:
char* p[5] = {(char*)malloc(50)};
to
char *p[5];
int i=0, n=5;
/* Allocate */
for (i=0; i<n; i++)
{
p[i] = malloc (sizeof (char) * 50);
}
/* Do work */
/* Deallocate */
for (i=0; i<n; i++)
{
free (p[i]);
}
EDIT1:
it looks like you wanted to achieve default assignment of the remaining locations like we can do with
char arr[10] = {0};
But in your case you have
char *p[5];
and for each location of p
you need a separate memory location which needs to be individually assigned/allocated to and freed/deallocated from like above.
EDIT2:
In your split function you are doing a terrible thing. If you have allocated the memory for p
in the main and then you pass it to the split
function, then why are you assigning a pointer again into the p
array elements. Each of the element of p
points to an entire array (block of memory) which can be used to hold a string. So you should copy the part of the string into p[i]
for some index i
, with strcpy
.
Also why are you returning the array? You have passed it as a pointer, and all the modifications you do to it in the function will persist after the return.
EDIT3:
Here is the modified split, made by applying minimum modifications to your code.
void split( char *result[], char *w, const char *delim)
{
int i=0;
char *p;
for(i=0, p=strtok(w, delim); p!=NULL; p=strtok(NULL, delim), i++ )
{
strcpy (result[i], p);
}
}
Here is a test main function:
int main (void)
{
char arr[128] = "10.08.1989";
char *p[5];
int i, n = 5;
for (i=0; i<n; i++)
{
p[i] = malloc (sizeof (char) * 50);
}
split (p, arr, ".");
printf ("%s\n", p[0]);
printf ("%s\n", p[1]);
printf ("%s\n", p[2]);
for (i=0; i<n; i++)
{
free (p[i]);
}
printf ("\n");
return 0;
}
Upvotes: 1
Reputation: 57764
The declaration char* p[5] = {(char*)malloc(50)};
has issues. It causes p[1]
, p[2]
, p[3]
, and p[4]
to be initialized to garbage, most probably, not many would be NULL, which is what the loop tests for.
There are also problems with the use of getline()
, most notably that the parameters are in the wrong order and not sufficiently indirected.
Upvotes: 5