c malloc in other function and structs - c

Im having problems with c and pointers. I keep grinding on this and it has to be easy. I have a struct and I allocate in one function, then pass the pointer back to the original function. But when I try to fill the values of the struct with other variables, and then print them or copy them , the app segfaults saying the memory address is out of bounds.
struct memcache_buffer{
int elements, action;
char keys[MAX_KEYS], values[MAX_KEYS], returns[MAX_KEYS]; //action 0 = delete , 1 = get 2 = set
}memcache_buffer;
struct memcache_buffer* memcache_allocate_buffer(int size){
struct memcache_buffer *buffer;
buffer =malloc(sizeof(struct memcache_buffer));
return buffer;
}
void memcache_set(char * key, char * value){
pthread_t process_t;
struct memcache_buffer *buffer=memcache_allocate_buffer(1);
char keys,values;
buffer->elements = 1;
buffer->action=2;
//printf("crash?\n");
printf("%s %s",key,value);
snprintf(buffer->keys[0],KEY_SIZE,"%s",key);
snprintf(buffer->values[0],VALUE_SIZE,"%s",value);
pthread_create(&process_t,NULL,memcache_process,buffer);
}
am I allocating the memory right? allocating memory and these pointers are sure rough, especially only messing with php in the past.

Here's your problem:
struct memcache_buffer{
char keys[MAX_KEYS], values[MAX_KEYS]
}
snprintf(buffer->keys[0],KEY_SIZE,"%s",key);
^^^
snprintf(buffer->values[0],VALUE_SIZE,"%s",value);
^^^
Drop the [0] or snprintf will try to dereference some bogus value.

Related

Heap corruption on malloc/calloc of char pointer field in struct

I have a struct defined like this
typedef struct {
char* Value;
unsigned int Length;
} MY_STRUCT;
I'm creating an array of these structs using calloc:
MY_STRUCT* arr = (MY_STRUCT*)calloc(50, sizeof(MY_STRUCT));
Then, in a loop, I'm accessing each struct and trying to allocate and assign a value to the Value field using calloc and memcpy:
int i;
for(i = 0; i < 50; i++)
{
MY_STRUCT myStruct = arr[i];
int valueLength = get_value_length(i);//for sake of example, we can assume that this function returns any value [1-99]
myStruct.Length = valueLength;
myStruct.Value = (char*) calloc(valueLength, sizeof(char));
memcpy(myStruct.Value, get_value(i), valueLength); //assume get_value(i) returns char* pointing to start of desired value
}
This code block crashes on the calloc line with Visual Studio indicating heap corruption. It doesn't fail the first time through the loop. Instead, it fails on the second pass when I'm trying to allocate a length 20 char array (first pass is length 5). I've tried using malloc as well, and I've tried using recommendations in:
Heap Corruption with malloc, struct and char *
Do I cast the result of malloc?
Nothing seems to mitigate the problem. I am originally a managed code programmer so my knowledge of memory allocation and management is not always the best. I'm sure I'm doing something boneheaded, but I'm not sure what. Any help would be greatly appreciated. Thank you!

How do you use malloc to allocate space for an array of structures?

I'm currently working on dynamically allocating my array of structures and I'm unsure how to continue. This is my structure:
struct Word_setup
{
char word[M];
int count;
} phrase[N];
I know malloc returns a pointer to a block of memory, but I'm not sure how this works when it comes to an array of structures.
If anyone could please clarify that would be much appreciated!
Probably you meant:
struct Word_setup {
char word[M];
int count;
};
It's a good idea to avoid defining variables in the same line as a struct definition anyway, to help with code readability.
Then you can allocate an array of these:
int main()
{
struct Word_setup *phrase = malloc(N * sizeof *phrase);
// use phrases[x] where 0 <= x < N
phrase = realloc(phrase, (N+5) * sizeof *phrase);
// now can go up to phrases[N+4]
free(phrase);
}
Of course you should check for failure and abort the program if malloc or realloc returns NULL.
If you also want to dynamically allocate each string inside the word then there are a few options; the simplest one to understand is to change char word[M] to char *word; and each time you allocate a phrase, write the_phrase.word = malloc(some_number); . If you allocate an array of words you'll need to loop through doing that for each word.
I suppose that N and M is a compile-time known constants. Then just use sizeof, .e.g.
struct Word_setup*ptr = malloc(sizeof(struct Word_setup)*N);
Maybe you want a flexible array member. Then, it should always be the last member of your struct, e.g.
struct Word_setup {
int count;
unsigned size;
char word[]; // of size+1 dimension
};
Of course it is meaningless to have an array of flexibly sized structures -you need an array of pointers to them.

How to properly malloc for array of struct in C

I will read in two set of char* (or strings) using strtok, and since those two set of chars are related, (address : command\n) I decided to use a structure.
struct line* array = (struct line*)malloc(sizeof(file) * sizeof(struct line*));
This line mallocing space for the function gives me a segmentation fault and was wondering if you can tell me a proper way to malloc space for it. For context, here is the rest of my code:
struct line
{
char* addr;
char* inst;
};
while loop{
x = strtok(line,": ");
y = strtok(NULL,"\n");
strcpy(array[i].addr,x); //assume that x and y are always 3characters
strcpy(array[i].inst,++y);
i++;
}
Allocating works the same for all types. If you need to allocate an array of line structs, you do that with:
struct line* array = malloc(number_of_elements * sizeof(struct line));
In your code, you were allocating an array that had the appropriate size for line pointers, not for line structs. Also note that there is no reason to cast the return value of malloc().
Note that's it's better style to use:
sizeof(*array)
instead of:
sizeof(struct line)
The reason for this is that the allocation will still work as intended in case you change the type of array. In this case this is unlikely, but it's just a general thing worth getting used to.
Also note that it's possible to avoid having to repeat the word struct over and over again, by typedefing the struct:
typedef struct line
{
char* addr;
char* inst;
} line;
You can then just do:
line* array = malloc(number_of_elements * sizeof(*array));
Of course don't forget to also allocate memory for array.addr and array.inst.
For what you have described, You do not need to allocate memory for your struct, rather, you need to allocate memory for the members char *addr;, and char *inst;. If you want to have a single copy of that structure, the first section of code illustrates how to initialize, and assign values. If you want an array, the second code example illustrates the differences.
This illustrates how to allocate memory for the members of a single struct line:
typedef struct
{
char* addr;
char* inst;
}LINE;
LINE line;
int main(void)
{
strcpy(line.addr, "anystring"); //will fail
line.addr = malloc(80);
line.inst = malloc(80);
strcpy(line.addr, "someString");//success;
strcpy(line.inst, "someOtherString");//success;
}
For array of struct line...
typedef struct
{
char* addr;
char* inst;
}LINE; //same struct definition
LINE line[10]; //but create an array of line here.
int main(void)
{
int i;
for(i=0;i<10;i++)
{
line[i].addr = malloc(80);
line[i].inst = malloc(80);
}
for(i=0;i<10;i++)
{
strcpy(line[i].addr, "someString");
strcpy(line[i].inst, "someOtherString");
}
//when done, free memory
for(i=0;i<10;i++)
{
free(line[i].addr);
free(line[i].inst);
}
}
Added to address comment
Addressing the comment under this answer from #Adam Liss, the following code illustrates the following improvements using strdup(): 1) Uses only memory needed. 2) Performs memory creation and copy operations in one step, so the the following blocks:
for(i=0;i<10;i++)
{
line[i].addr = malloc(80);
line[i].inst = malloc(80);
}
for(i=0;i<10;i++)
{
strcpy(line[i].addr, "someString");
strcpy(line[i].inst, "someOtherString");
}
Become:
for(i=0;i<10;i++)
{
line[i].addr = strdup("someString");
line[i].inst = strdup("someOtherString");
}
One more note: Error handling was not included in examples above to avoid muddling up focus on the main concepts: But for the sake of completeness, because both malloc() and strdup() can fail, actual usage for each of these two functions, should include a test before using, eg:
Rather than
line[i].addr = strdup("someString");
line[i].inst = strdup("someOtherString");
The code should include
line[i].addr = strdup("someString");
if(!line[i].addr)
{
//error handling code here
}
line[i].inst = strdup("someOtherString");
if(!line[i].inst)
{
//error handling code here
}

Changing values in elements of an array of structs

I am working on an assignment and ran into challenging problem. As far as I'm concerned and from what I've learnt the code that follows should be correct however it does not work. Basically what I am trying to is copy a string value into the variable member of a structure the is part of an array passed into a method as a pointer. What am I missing?
typedef struct
{
char * name; //variable in struct I am trying to access
} Struct;
void foo(Struct * arr) //array of Structs passed into function as a pointer
{
int i = 0;
while(i++ < 2)
{
arr[i].name = malloc(sizeof(char *)); //assigning memory to variable in each Struct
arr[i].name = strdup("name"); //copying "name" to variable in each Struct
printf("C - %s\n", arr[i].name); //printing out name variable in each Struct
}
}
main()
{
Struct * arr; //defining pointer
arr = calloc(2, sizeof(Struct)); //allocating memory so pointer can hold 2 Structs
foo(arr); //calling function foo passing pointer into function
return 0;
}
This code compiles and runs however it does not do what it is designed to do. Forgive me if it is something trivial. I am new to the language C
Two issues:
while(i++ < 2) This line changes the value of i as soon as it checks it, so your loop body will not be the same as it was checked.
arr[i].name = strdup("name"); overwrites the value of the .name pointer, causing a memory leak of the memory you malloc()'ed earlier.
Extending on 2 pointed out correctly already,
arr[i].name = strdup("name");
Even if you use following instead of above,
strcpy(array[i].name, "name");
you haven't allocated enough bytes to store the string i.e. this is wrong
arr[i].name = malloc(sizeof(char *));
// even if pointer is 8 byte here, concept isn't right
Should be something like
arr[i].name = malloc(strlen("name")+1);
// or MAX_SIZE where it is greater than the possible "name".
Or better yet, remove the malloc at all, strdup takes care of allocation itself
This is not answering your question directly, but addresses an issue to big to put into a comment...
Additional issue: You probably did not intend to allocate only a (char *) worth of memory to a variable intended to hold at least "name". Change;
arr[i].name = malloc(sizeof(char *));
to:
arr[i].name = malloc(sizeof(char)*strlen("name")+1); //+1 for '\0'
or better yet, use char *name="name";, then:
arr[i].name = malloc(sizeof(char)*strlen(name)+1);
Even more general (and better):
char *name;
name = malloc(strlen(someInputString)+1);
//do stuff with name...
free(name);
Now, you can allocate name to any length needed based on the length of someInputString.
[EDIT]
Etienz, I wanted to address one more thing, alluded to by #H2CO3 above, but not really explained, that I think might be useful to you:
Regarding your desire to have room for two structs, because you typedef'd your struct, you can simply do something like this: (but I am going to change the name you used from Struct to NAME :) The whole point being that when a struct is created as an array, you do not need to use calloc or malloc to create space for them, it is done as shown below...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char *name;
}NAME;
//use new variable type NAME to create global variables:
NAME n[2], *pN; //2 copies AND pointer created here
//prototype func
int func(NAME *a);
int main()
{
pN = &n[0]; //pointer initialized here
func(pN); //pointer used here (no malloc or calloc)
printf("name1 is %s\nname 2 is %s", pN[0].name, pN[1].name);
return 0;
}
int func(NAME *a)
{
char namme1[]="andrew";
char namme2[]="billebong";
//You DO have to allocate the members though
a[0].name = malloc(strlen(namme1)+1);
a[1].name = malloc(strlen(namme2)+1);
strcpy(a[0].name, namme1);
strcpy(a[1].name, namme2);
return 0;
}

Segmentation fault when initialization array

I have a structure called string
typedef struct {
char *s;
int len;
} string_t;
typedef struct {
uint32_t numb;
} msg_t;
where in the function
void myfunct()
{
msg_t msg;
memset(&msg, 0, sizeof(msg));
msg.numb = 1;
char *ClientSendBuf[sizeof(msg)];
string_t buffer = {ClientSendBuf[sizeof(msg)],strlen(ClientSendBuf[sizeof(msg)])};
}
Tried to initialize an array (basically a buffer that I need to send later on) using UDP,
but it gives me an error of segmentation fault (on the third line in void myfunct.
So the thing with buffer is that it should be a type of string_t, how can I fix this segmentation fault?
P.S. I forgot to mention, I want to copy the whole structure to the buffer variable (that should be type string_t) using memcopy. So am I doing the wrong thing above? How can I do this?
There are a few things you have to consider in initializing your structure, as it has a pointer member char *s simple assignment will not work. Simple assignment will just copy the pointer address and not the content it is pointing to.
There are a few problems in your assignment code:
1. You declared an array of char * with sizeof(msg) elements, none of which are allocated memory; but your structure need char * and not char *[]
2. You are accessing an array element which is out of bounds (ClientSendBuf[sizeof(msg)]) and also not pointing to any valid address.
You can create a simple char array & copy it to the structure. As you are using a pointer member it is your responsibility to allocate memory and free memory.
Hope the code below can provide you with some references:
void myfunct()
{
msg_t msg;
memset(&msg, 0, sizeof(msg));
msg.numb = 1;
char ClientSendBuf[] = "This is my message";
string_t buffer = {
strdup(ClientSendBuf), /*Can return NULL so add error check*/
strlen(ClientSendBuf)
};
/** Or **/
string_t buffer;
buffer.s = malloc(strlen(ClientSendBuf)+1);
if(NULL == buffer.s)
{
/* Memory allocation failed. Handle error.*/
}
/* Zero fill */
memset(buffer.s, 0, strlen(ClientSendBuf)+1);
strcpy(buffer.s, ClientSendBuf);
buffer.len = strlen(ClientSendBuf);
/*Opeartions with buffer*/
/*Call free in both cases !*/
free(buffer.s);
}
Hope this help!
ClientSendBuf - put some thing in it and also put it on the heap.
The problem is that you don't allocate memory to any element of ClientSendBuf. You should use malloc here to first allocate the memory.
I see two things that are wrong. First, accessing ClientSendBuf[sizeof(msg)] is undefined behavior, because that character is after the end of CliendSendBuf. Then you're assigning a char (namely ClientSendBuf[sizeof(msg)]) when a char * is expected.
And if you want to use buffer outside that function you have to put ClientSendBuf on the heap, because it will be overwritten by other stack frames after you exit (i.e. sort of deleted), so the pointed data will be throwed off.
Now, since you want a copy of the whole ClientSendBuff, you need an array of string_t. Then, you assign every pointer in ClienSendBuff to buffer:
char *ClientSendBuff[sizeof(msg)];
string_t buffer[sizeof(msg)];
int i;
for(i = 0; i < sizeof(msg); i++) {
ClientSendBuff[i] = malloc(100); // you have to initialize (and free when
buffer[i].s = ClientSendBuff[i]; // you don't need them anymore) every pointer
buffer[i].len = 100;
}
But I'm not sure if I got your point. How can a char * [] fit in a char*?

Resources