Segfault when returning an int value; - c

I know this question might sound quite stupid, but I've tried my best and I can't seem to have solved issues with this code:
struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement));
int ind = 0;
char** yay = strsplit(code, ";");
char* a = *yay;
while (a != NULL) {
puts(a);
if (strncmp(a, "#", 1)) {
struct bacon_statement statm;
int valid = bacon_make_statement(a, statm);
if (valid != 0) { return valid; }
statms[sta] = statm;
}
sta++;
*(yay)++;
a = *yay;
}
puts("Running BACON INTERNAL MAKE");
int ret = bacon_internal_make(statms, internal);
printf("%d\n", ret);
return ret;
It segfaults when returning, since it the printf is executed alright., and another printf call /after/ the function is called (on int main()) doesn't print anything at all.
I'm sorry if this sounds too specific, but I don't know where else to get help.

Apparently you are corrupting the stack somehow.
your line does not initialize the pointer:
struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement));
but you write to it like this, which will have undefined behavior:
statms[sta] = statm;
Easiest way to fix is probably to restore the malloc (provided the size is correct)
struct bacon_statement* statms = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement));

Seems like a stack overrun, you keep assigning data to the buffer (statms) without checking for boundaries. Sooner or later, the return address (which is on the stack) will be overridden and when return is reached, the address to return to will be corrupted. and there is your segmentation fault.

Try doing something like:
int count = 0;
char *ptr = strchr(code, ';');
while (ptr) {
count++;
ptr = strchr(ptr + 1, ';');
}
to predict the number of statements, and then:
struct bacon_statement* statms = (struct bacon_statement*) malloc(
count * sizeof(struct bacon_statement));
to allocate enough bacon_statement slots. Alternatives are probably more difficult: a linked list or other mutable structure; or using realloc to increase the size of the array, keeping a note of how many sots you have left.
The mistake can still be in the other functions though!

The code does too much. Let me summarise:
struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement));
int ind = 0;
char** yay = strsplit(code, ";");
char* a;
while ((a = *yay)) {
puts(a);
if (strncmp(a, "#", 1)) {
struct bacon_statement statm;
int valid = bacon_make_statement(a, statm);
if (valid != 0) { return valid; }
statms[sta] = statm;
}
sta++;
*(yay)++;
}
puts("Running BACON INTERNAL MAKE");
int ret = bacon_internal_make(statms, internal);
printf("%d\n", ret);
return ret;
But we can get more compact than that:
struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement));
int ind = 0;
char** yay;;
char* a;
for (yay = strsplit(code, ";"); (a = *yay); *(yay)++ ) {
puts(a);
if (strncmp(a, "#", 1)) {
struct bacon_statement statm;
int valid = bacon_make_statement(a, statm);
if (valid != 0) { return valid; }
statms[sta] = statm;
}
sta++;
}
puts("Running BACON INTERNAL MAKE");
int ret = bacon_internal_make(statms, internal);
printf("%d\n", ret);
return ret;
Now let's remove the silly stringcompare:
struct bacon_statement* statms;// = (struct bacon_statement*)malloc(3000 * sizeof(struct bacon_statement));
int ind = 0;
char** yay;
char* a;
for (yay = strsplit(code, ";"); (a = *yay); *(yay)++ ) {
puts(a);
if (*a != '#') {
struct bacon_statement statm;
int valid = bacon_make_statement(a, statm);
if (valid != 0) { return valid; }
statms[sta] = statm;
}
sta++;
}
puts("Running BACON INTERNAL MAKE");
int ret = bacon_internal_make(statms, internal);
printf("%d\n", ret);
return ret;
Still does not make sense. IMO the OP wants to loop trough an array of string-pointers (yay) and process each string in it. Especially the *(yay)++ looks awkward.
Maybe with the '#' he wants to skip comments. I'd expect something like:
sta=0;
for (yay = strsplit(code, ";"); (a = *yay); yay++ ) {
int err;
if (*a == '#') continue;
/* make bacon from a */
err = bacon_make_statements(a, statms[sta] );
if (err) return err;
sta++; /* could overflow ... */
}
/* you need the number of assigned struct members ("sta") to this function */
return bacon_internal_make(statms,sta internal);
On second thought, my guess is that the strsplit() function return a pointer to an automatic ("stack") variable. Or the *yay variable is incremented beyond recognition. Or the statms[] array is indexed out of bounds.

Is it possible that you meant to use ind instead of sta as the array index variable and sta is uninitialized?

Related

What's wrong with my realloc doing on 2d-array

I am solving binary tree paths leet code programming question 257. I am having issue for one of the larger input where my code is getting segmentation fault. I suspect that there is an problem with my realloc but I am not able to figure it out.
Below is my approach:
Initially I started by dynamically allocating 80 bytes of memory of type char (80/8 = 10 rows)and storing the returned address to char **res variable.
char ** res = (char **)malloc(sizeof(char *) * sum);
I am calling findpath function recursively to find all the binary tree paths. Whenever one path is found , I dynamic allocate 100 bytes for each row index.
res[resIdx] = (char *)malloc(sizeof(char) * 100);
I have one global variable resIdx which points to the current row index where I copy the found binary tree path and increment the global variable resIdx.
if the resIdx becomes greater then total number of rows which was previously allocated then I do realloc of the memory but it looks like realloc is getting failed.
if (resIdx >= sum)
{
sum = sum + 10;
res = (char **)realloc(res,sizeof(char *) * sum); //Any issue here?
}
Can anyone please help me to figure out what's wrong I am doing in my code. Below is my full code
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int sum;
int resIdx;
void findpath (struct TreeNode* root, int *ls,int ls_idx,char **res);
char ** binaryTreePaths(struct TreeNode* root, int* returnSize){
if (root == NULL)
{
*returnSize = 0;
return NULL;
}
resIdx = 0;
sum = 10;
char ** res = (char **)malloc(sizeof(char *) * sum);
int ls[100];
findpath(root,&ls[0],0,res);
*returnSize = resIdx;
return &res[0];
}
void findpath (struct TreeNode* root, int *ls,int ls_idx,char **res)
{
char temp[100];
int l=0,i=0;
if (root->left == NULL && root->right == NULL)
{
ls[ls_idx] = root->val;
ls_idx+=1;
if (resIdx >= sum)
{
sum = sum + 10;
res = (char **)realloc(res,sizeof(char *) * sum);
}
res[resIdx] = (char *)malloc(sizeof(char) * 100);
while (i < ls_idx)
{
if (i==0)
{
l = l + sprintf(&temp[l], "%d", ls[i]);
}
else
{
l = l + sprintf(&temp[l], "->%d", ls[i]);
}
i++;
}
strcpy(res[resIdx],temp);
resIdx++;
return;
}
ls[ls_idx] = root->val;
if (root->left != NULL)
{
findpath(root->left,ls,ls_idx+1,res);
}
if (root->right != NULL)
{
findpath(root->right,ls,ls_idx+1,res);
}
return;
}
The last argument to your findPath function is declared as a char** type; thus, when you make the call findpath(root,&ls[0],0,res); in binaryTreePaths, where the res variable is a char** type, a copy of that pointer is passed to the findPath function (most likely, but not necessarily, by placing that copy on the stack).
Then, if reallocation is required, the res = (char **)realloc(res,sizeof(char *) * sum); line in that function overwrites the value in the passed copy and, at the same time (if the call is successful – vide infra), will (probably) invalidate (i.e. free) the memory referenced by the previous address in that res copy. Thus, when control returns to the calling binaryTreePaths function, its own version of res will not have been modified and will remain pointing to that (now invalid) memory.
So, in order for your findPath function to be able to modify the given res argument, that must be passed as a pointer – in this case, a pointer to a char**, which will be of type char***; then, when called, you will need to pass the address of the res variable in binaryTreePaths.
Note also that directly overwriting a pointer in a call to realloc, as you have done in the line of code quoted above is dangerous. This is because, should that call fail, then you have lost the original data pointer (it will have been overwritten with NULL) and error recovery will be very difficult. You should save the return value in a temporary variable and only replace your original if the call succeeds.
With the code you have provided, I cannot properly test for any other errors but, taking the points above in hand, the below is a possible fix. See also: Do I cast the result of malloc?
int sum;
int resIdx;
void findpath(struct TreeNode* root, int* ls, int ls_idx, char*** res); // Note last argument type!
char** binaryTreePaths(struct TreeNode* root, int* returnSize)
{
if (root == NULL) {
*returnSize = 0;
return NULL;
}
resIdx = 0;
sum = 10;
char** res = malloc(sizeof(char*) * sum);
int ls[100];
findpath(root, &ls[0], 0, &res); // Pass ADDRESS of res
*returnSize = resIdx;
return &res[0];
}
void findpath(struct TreeNode* root, int* ls, int ls_idx, char*** res)
{
char temp[100];
int l = 0, i = 0;
if (root->left == NULL && root->right == NULL) {
ls[ls_idx] = root->val;
ls_idx += 1;
if (resIdx >= sum) {
sum = sum + 10;
char** test = realloc(*res, sizeof(char*) * sum);
if (test == NULL) {
// Handle/signal error
return;
}
*res = test; // Only replace original if realloc succeeded!
}
(*res)[resIdx] = malloc(sizeof(char) * 100);
while (i < ls_idx) {
if (i == 0) {
l = l + sprintf(&temp[l], "%d", ls[i]);
}
else {
l = l + sprintf(&temp[l], "->%d", ls[i]);
}
i++;
}
strcpy((*res)[resIdx], temp);
resIdx++;
return;
}
ls[ls_idx] = root->val;
if (root->left != NULL) {
findpath(root->left, ls, ls_idx + 1, res);
}
if (root->right != NULL) {
findpath(root->right, ls, ls_idx + 1, res);
}
return;
}

How to return a char** as a function argument

I have a function that returns a pointer to pointers of chars (char**). The function takes 2 arguments
int* num_paths: a pointer to an integer to indicate the number of strings to be returned.
int* errno: a pointer to an integer to indicate an error code. This can contain different values, so I cannot simply check if NULL is returned in case of error.
Some example code is written below (with the majority of error checks omitted for simplicity):
char** get_paths(int* num_paths, int* errno) {
char* path1 = NULL;
char* path2 = NULL;
char** paths = NULL;
if(errno == NULL) {
printf("Set errno in case of error, but cannot dereference NULL pointer\n");
goto exit;
}
path1 = calloc(1, strlen("foo") + 1);
path2 = calloc(1, strlen("bar") + 1);
strcpy(path1, "foo");
strcpy(path2, "bar");
*num_paths = 2;
paths = calloc(1, *num_paths*sizeof(char *));
paths[0] = path1;
paths[1] = path2;
*errno = 0;
exit:
return paths;
}
int main(void) {
char** paths = NULL;
int num_paths = 0;
int errno = 0;
paths = get_paths(&num_paths, &errno);
if(errno != 0) {
return -1;
}
for(int i = 0; i < num_paths; i++) {
printf("%s\n", paths[i]);
free(paths[i]);
}
free(paths);
}
The problem I have with this is that I can't set the error code in case a NULL pointer is passed as argument for errno. You could argue that this is a user error, but I would still like to avoid this situation in the first place.
So my question is: can I rewrite my get_paths function such that it returns an integer as error code, but also returns a char** through the function arguments without resorting to char*** like in the following example:
int get_paths_3(char*** paths, int* num_paths) {
char* path1 = NULL;
char* path2 = NULL;
path1 = calloc(1, strlen("foo") + 1);
path2 = calloc(1, strlen("bar") + 1);
strcpy(path1, "foo");
strcpy(path2, "bar");
*num_paths = 2;
*paths = calloc(1, *num_paths*sizeof(char *));
(*paths)[0] = path1;
(*paths)[1] = path2;
return 0;
}
This is pretty much the only case where "three star" pointers are fine to use. It's fairly common practice in API design to reserve the return value for error codes, so this situation isn't uncommon.
There are alternatives, but they are arguably not much better. You could abuse the fact that void* can be converted to/from char** but it isn't much prettier and less type safe:
// not recommended
int get_paths_4 (void** paths, size_t* num_paths)
{
char* path1 = calloc(1, strlen("foo") + 1);
char* path2 = calloc(1, strlen("bar") + 1);
strcpy(path1, "foo");
strcpy(path2, "bar");
*num_paths = 2;
char** path_array;
path_array= calloc(1, *num_paths*sizeof(char *));
path_array[0] = path1;
path_array[1] = path2;
*paths = path_array;
return 0;
}
...
void* vptr;
size_t n;
get_paths_4 (&vptr, &n);
char** paths = vptr;
for(size_t i=0; i<n; i++)
{
puts(paths[i]);
}
A more sound alternative might be wrap all your parameters into a single struct type and pass that one as a pointer.
Unfortunately you cannot mixing return types in C is a terrible mistake and should not be done, you can either:
return the pointer you need and add a error code to a variable
return the error code and add the pointer to a variable
Both are valid strategies and I'd pick the one that matches the rest of your code to have consistency.

Segmentation Fault: double free or corruption (fast top)

I've a problem when I run this piece of code: a Segmentation Fault that appears during the free instruction of percorso. I cannot find the problem.
void ricerca(char nome[], struct node *radice, char percorso[], struct stringhe **indice) {
struct node *punt = radice;
int dim = len(percorso);
char *prov = NULL;
if (dim > 0) {
prov = malloc(2 * dim * sizeof(char));
prov[0] = '\0';
strcpy(prov, percorso);
free(percorso); //--------------------->here the SegFault
}
struct stringhe *nuovo = NULL;
int i = 0, fine = 0;
char *perc_orig = NULL;
if (punt != NULL) {
if (punt->array != NULL) {
dim = len(prov) + len(punt->nome) + 2;
percorso = malloc(dim * sizeof(char));
percorso[0] = '\0';
if (prov!=NULL)
strcpy(percorso, prov);
strcat(percorso, "/");
strcat(percorso, punt->nome);
perc_orig = malloc(dim * sizeof(char));
for (i = 0; i < N; i++) {
if (punt->array->vet[i] != NULL) {
perc_orig[0] = '\0';
strcpy(perc_orig, percorso);
ricerca(nome, punt->array->vet[i], perc_orig,indice);
}
}
free(perc_orig);
}
if (strcmp(nome,punt->nome) == 0) {
free(percorso);
dim = len(prov) + len(punt->nome) + 2;
percorso = malloc(dim * sizeof(char));
inizializza(percorso, dim);
if (prov != NULL)
strcpy(percorso, prov);
strcat(percorso, "/");
strcat(percorso, punt->nome);
nuovo = malloc(sizeof(struct stringhe));
nuovo->next = NULL;
nuovo->str = malloc(dim * sizeof(char));
inizializza(nuovo->str, dim);
strcpy(nuovo->str, percorso);
nuovo->next = (*indice);
*indice = nuovo;
}
while (punt->chain != NULL && fine == 0) {
ricerca(nome, punt->chain,prov, indice);
fine = 1;
if (prov!=NULL)
free(prov);
}
}
}
The len function is like strlen, but the difference is that I've made it myself.
the context is:
void find(char nome[], struct node *radice) {
char *perc = NULL;
struct stringhe **inizio = NULL;
inizio = malloc(sizeof(struct stringhe*));
*inizio = NULL;
int i = 0;
for (i = 0; i < N; i++) {
if (radice->array->vet[i] != NULL) {
perc = NULL;
ricerca(nome, radice->array->vet[i], perc, inizio);
}
}
if (*inizio != NULL) {
insertion(inizio);
stampap(*inizio);
} else
printf("no\n");
}
And the data structures:
struct tab {
struct node *vet[64];
};
struct node {
char nome[255];
int num;
int tipo;
char *dati;
struct tab *array;
struct node *chain;
};
This is really weird:
if (some condition)
free(percorso);
Later on we have:
perc_orig = malloc(dim*sizeof(char));
for(something){
if(something){
ricerca(nome,punt->array->vet[i],perc_orig,indice);
}
}
free(perc_orig);
If that if conditions happens, perc_orig will be freed twice. Kaboom.
I think your problem is you think that ricerca(..., char percico[], ...) copies percico. It doesn't; it's really ricerca(..., char *percico, ...) so you ended up freeing the memory twice.
the sizing for the char arrays needs to allow for the trailing NUL ('\0') character.
ALL fields that are referenced by strcpy() and similar functions need to have ALL source character arrays NUL terminated.
The code does not seem to be allocating enough room for those trailing NUL bytes NOR terminating every character array with a NUL char.
Segmentation fault occurs when you initialize a character pointer to NULL and try to point it to a not null value
For example,
char *a=NULL;
a='a';
Will cause segmentation fault. To avoid this you can try to initialize as,
char *a;
a='a';

Segmentation fault when trying to access pointer in struct [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm trying to access a pointer inside of a struct, I tried placing * in front of the struct pointer
to access the pointer inside the struct, but it segfaults.
code segfaults on *ptr->numberOfClients = clients;
int getNumberOfClients(struct fuzzerObj *ptr)
{
int rtrn;
long clients;
char *input;
char *holder = NULL;
printf(BOLDBLUE"How many clients will you be connecting to this fuzz server?\n"RESET);
printf(BOLDBLUE"---> "RESET);
rtrn = getUserInput(&input);
if(rtrn < 0)
{
errorHandler("Can't Get User input\n", FUNCTION_ID_GET_NUMBER_OF_CLIENTS);
return -1;
}
if (strlen(input))
{
clients = strtol(input, &holder, 10);
if (input == holder)
{
errorHandler("invalid long conversion\n", FUNCTION_ID_GET_NUMBER_OF_CLIENTS);
return -1;
}
}
else
{
errorHandler("No Value To Compute\n", FUNCTION_ID_GET_NUMBER_OF_CLIENTS);
return -1;
}
*ptr->numberOfClients = clients;
free(input);
return 0;
}
int getUserInput(char **buf)
{
int i = 0, max = 1024, c;
*buf = reallocarray(NULL, 1025, sizeof(char *));
if(*buf == NULL)
{
errorHandler("Mem Error\n", FUNCTION_ID_GET_USER_INPUT);
free(*buf);
return -1;
}
while (true) { // skip leading whitespace
c = getchar();
if (c == EOF) break; // end of file
if (!isspace(c)) {
ungetc(c, stdin);
break;
}
}
while (true) {
c = getchar();
if (isspace(c) || c == EOF) // at end, add terminating zero
buf[i] = 0;
break;
}
*buf[i] = c;
if (i==max-1) { // buffer full
max = max+max;
*buf = (char*)realloc(*buf,max); // get a new and larger buffer
if (buf == 0)
{
errorHandler("Realloc Error\n", FUNCTION_ID_GET_USER_INPUT);
return -1;
}
}
i++;
return 0;
}
and here's the struct
struct fuzzerObj
{
int parserResponse;
int *numberOfClients;
int *clientFuzzerType[1024];
int *clientSockets[1024];
int *clientApplication[1024];
int *clientFuzzer[1024];
int *connectedClients;
int *socket;
int *fuzzer;
int *application;
dispatch_queue_t queue;
};
There is a major problem that I see (unless you've not shown it in your code snippets). numberOfClients is declared as such:
struct fuzzerObj
{
...
int *numberOfClients;
...
};
Before you assign an int to it. You must assign memory to store the int:
1.
ptr->numberOfClients = malloc(sizeof(*(ptr->numberOfClients)));
*(ptr->numberOfClients) = clients;
...
free(ptr->numberOfClients);
2.
int temp;
ptr->numberOfClients = &temp;
*(ptr->numberOfClients) = clients;
...
// Write to a file here???
Another question... why are the fields of fuzzerObj pointers? If you make them ints instead of pointers to ints, you wouldn't have the difficulties you're experiencing.
EDIT
The second method shown above is not safe because once the function that has declared temp returns, temp no longer exists, and therefore numberOfClients doesn't have valid memory, and should not be used.
It is totally unclear why data member numberOfClients defined as a pointer instead of to be an object of type int
int *numberOfClients;
Try the following
ptr->numberOfClients = ( int * )malloc( sizeof( int ) );
if ( ptr->numberOfClients ) *ptr->numberOfClients = clients;
Also take into account that variable clients is defined as
long clients;
In some implementations sizeof( lomg ) can be greater than sizeof( int ).
It is in general a bad design. It is unclear whether data members of the structures were initialized and corresponding memory were allocated.

Memory allocation and core dump for pointers to structures in c

Sorry I'm new to memory allocation and structure (so most probably it's some silly thing I've missed). I've got the following code which is core dumping on Solaris. I'm not also sure how to add more elements later (should I realloc memory?)
enum field_type
{
FLD_STRING,
FLD_SHORT
};
typedef struct {
long id;
char *name;
field_type type;
void *value;
} myStruct_t ;
typedef struct {
long id;
const char *name;
field_type type;
const char *descr;
} myStructDef_t;
myStructDef_t Alldef[] =
{
{0, "FirstField", FLD_STRING, "First Field Of Structure"},
{1, "SecondField", FLD_STRING, "Second Field Of Structure"},
{-1}
};
int main()
{
myStruct_t *p_struct;
char tmp[100] = {'\0'};
long id = 0;
if(NULL == (p_struct= structAlloc(1024)))
{
print("Failed allocating memory\n");
return 0;
}
sprintf(tmp, "Test Adding value");
addValueToStruct(p_struct, id, (void *)tmp);
}
myStruct_t *structAlloc(long size)
{
myStruct_t *tmp = (myStruct_t *) calloc(size, sizeof *tmp);
if(NULL != tmp)
tmp->id = -1;
return tmp;
}
int addValueToStruct(myStruct_t *p_struct, long id, (void *)value)
{
myStruct_t *bkStruct = p_struct;
myStructDef_t *def = NULL;
if(-1 == getIdDefinition(def, id))
{
printf("Failed to find definition for id [%ld]", id);
return -1;
}
// Core dumping on 1st line below
bkStruct->id = def->id;
sprintf(bkStruct->name, "%s", def->name);
bkStruct->type = def->def->type;
if(FLD_SHORT == bkStruct->type)
memcpy(bkStruct->value, value, sizeof(*(short *)value));
else if(FLD_STRING == bkStruct->type)
memcpy(bkStruct->value, value, sizeof(*(char *)value));
return 0;
}
int getIdDefinition(myStructDef_t *def, long id)
{
myStructDef_t *AllDefsTmp = Alldef;
bool found = false;
while( -1 != AllDefsTmp->id)
{
if(id == AllDefsTmp->id)
{
def = AllDefsTmp;
found = true;
break;
}
AllDefsTmp ++;
}
if(!found)
return -1;
return 0;
}
Thanks :)
myStructDef_t *def = NULL;
if(-1 == getIdDefinition(def, id))
{
printf("Failed to find definition for id [%ld]", id);
return -1;
}
// Core dumping on 1st line below
bkStruct->id = def->id;
Calling GetIdDefinition(def, id) will fill in def within the that function, but won't change the value within the addValueToStruct function - you need a double pointer (in C) or reference (in C++), so that you can change the value of def itself. (Or you could of course just return the value you found, instead of -1 or 0 return value).

Resources