How to use pointers when calling a function [duplicate] - c

This question already has answers here:
Changing address contained by pointer using function
(5 answers)
Closed 5 years ago.
I have some issue with programming in C. I have a structrure, that goes like
typedef struct Hash_Funct{
char* name;
Var_Table * List_of_Variables; ///pointer to list of variables
} Hash_Funct;
And in certain point of code, I want to inicialize the structure with:
Hash_Funct tmp = (Hash_Funct*) malloc(sizeof(Hash_Funct));
tmp->name=name;
Init_ID_Table(tmp->List_of_Variables);
Where the Init_ID_Table(); is defined as:
void Init_ID_Table(Var_Table *table){
table = (Var_Table*) malloc ( sizeof(Var_Table) );
for(int i=0; i< SIZE;i++){
(*table)[i] = NULL;
}
}
However, at the end of this code, it doesnt seems that the Init_ID_Table() had any affect on the * List_of_Variables pointer (which should now point onto a table of size SIZE and have all its elements set to NULL). Can anyone at least tell me what is going on if not how to change it to work as expected?
Thank you very much,
Adam

Variables are passed by value, assigning to the parameter variable in the function has no effect on the caller's variable.
You need to pass a pointer to the struct member, and indirect through it to modify the caller's variable.
void Init_ID_Table(Var_Table **table) {
Var_Table *temp_table = malloc ( sizeof(Var_Table) );
for (int i = 0; i < SIZE; i++) {
temp_table[i] = NULL;
}
*table = temp_table;
}
Then you would call it this way:
Init_ID_Table(&(tmp->List_Of_Variables));

Related

Writing to array of pointers in C

I need to write the pointer address of a struct (struct is called "Post") that has reposted another Post. There's a fixed return type called result with the following declaration:
struct result {
void** elements;
size_t n_elements;
};
For the Post struct, it has the following declaration:
struct post {
uint64_t pst_id;
uint64_t timestamp;
size_t* reposted_idxs;
size_t n_reposted;
};
Here's my code:
result* find_all_reposts(post* posts, size_t count, uint64_t post_id, query_helper* helper) {
result * ret_result = (result *) malloc(sizeof(result));
ret_result->elements[100];
ret_result->n_elements = 0;
for(int i = 0; i < count; i++){
post * temp = &posts[i];
size_t total_reposted = temp->n_reposted;
if(total_reposted > 0){
for(int q = 0; q < total_reposted; q++){
int index_of_repost = temp->reposted_idxs[q];
ret_result->elements[q] = &posts[index_of_repost];
ret_result->n_elements++;
}
}
}
return ret_result;
}
However I get a SEGV error for ret_result->elements[q] = &posts[index_of_repost];. I thought it could be originally that I hadn't initialised the elements field in the ret_result struct but I receive warning: statement with no effect for that:
warning: statement with no effect [-Wunused-value]- ret_result->elements[100];
I'm thinking that the void ** type for the elements field in result might be messing me around. From what I understand that's a pointer to a pointer which can obviously be an array and hence is basically a pointer to an array of posts?
I should clarify that count is the number of posts and that the returned-result is managed separately and hence any heap-allocated memory is freed in a separate process.
Thanks for your help :)
You haven't initialized ret_result->elements to anything. The statement ret_result->elements[100] is a no-op, the only reason you're not segfaulting there too is because your compiler is cutting it out. If you want that field to be a pointer to an array of size 100 you must initialize it with malloc. I'm not sure why you're declaring it to be a void ** double pointer here, but if it must be that way then something like this might work:
ret_result->elements = malloc(100 * sizeof(struct post *));
The call's arguments could also be 100 * sizeof(void *), but it might be a little what you intend to store there if you specify the struct to which the data will be pointing.

C - Array initialization inside function [duplicate]

This question already has answers here:
Initializing a pointer in a separate function in C
(2 answers)
C Programming: malloc() inside another function
(9 answers)
Closed 5 years ago.
In the main function, I have some null pointer like
double *data_1;
This pointers are passed as argument to other function which determine how many components must have data_1 and uses malloc to assign a memory block and store information:
void function(double *data) {
...
data = (double *) malloc((size_t) (Ndata) * sizeof(double));
for(i = 0; i < (Ndata); i++) {
data[i] = sys->points[i][coordinate];
}
}
This code isn't working. I used GDB to examine bug and I encounter that inside function() the assignment works, but when execution returns to the main() function, the array data_1 wasn't modified although the memory to which it points is exactly the same to which points "data" argument in function().
Why is this happening?
The pointer you passed to your function is passed by value. It is copied to the parameter data. Inside you are allocating memory to data which will make it to point to the allocated memory instead of the pointer you passed. Any modification done to this pointer is not reflected to the pointer you passed. You need to return the pointer to the allocated memory.
double *function() {
...
double *data = malloc((size_t) (Ndata) * sizeof(double));
for(i = 0; i < (Ndata); i++) {
data[i] = sys->points[i][coordinate];
}
return data;
}

C: Why is the print statement changing the value of my struct member? [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 5 years ago.
I have a struct that looks like this:
typedef struct
{
int *numberList;
int size;
int maxNumber;
} list;
Then I have this method to create a list:
list* createList(int maxNumber)
{
list l;
l.size = 0;
l.numberList = malloc(maxNumber*sizeof(int));
list* ptr = &l;
return ptr;
}
Then I have this method in the works:
int updateSize(list *ls)
{
ls->size++;
printf("This is a print statement.\n");
return 0;
}
I check the value of size in my main method and it works fine for both initialization and the update, but when it gets to the print statement, size changes to a large incorrect number (garbage value?), e.g. 4196190 instead of 1. In the full version of my code I also use malloc() in my updateSize() for my numberList and even that keeps the results as they should be up until the print statement. My question is: What is it about the print statement that alters the member(s) of my struct?
You return the address of l from createList, but l is local to that function, so the space it occupies can (and apparently, is) used for other things, overwriting what was there before.

How do you properly allocate a struct inside a function? [duplicate]

This question already has answers here:
How to malloc inside a function and return pointer in C?
(3 answers)
Closed 7 years ago.
I have this code which is where I've narrowed down the problem. When I step through with the debugger it seems to be fine but as soon as it leaves the function, freeCount loses the value assigned to it. It is supposed to be 100, and until the last } it shows it assigned the value fine but as soon as the function breaks it goes back to some 16 digit value. Can anyone point out my error?? much appreciated!
void initializeTree(TREE* empList)
{
empList = (TREE *)malloc(sizeof(TREE));
int i;
for (i = 1; i <= maxEmp; i++)
{
time_t seed = time(null);
empList->freeList[i] = (int)(rand() % seed);
}
empList->freeCount = maxEmp;
empList->parent = null;
empList->root = null;
}
It's because in C arguments to functions are passed by value, which means they are copied. So when you pass a pointer to a function, the functions receives a copy of the pointer, and as you know changing a copy will not change the original.
C doesn't have argument passing by reference, but it can be emulated using pointers. So to pass a pointer by reference you need to pass a pointer to the pointer.
void initializeTree(TREE** empList)
{
*empList = malloc(sizeof(TREE));
...
(*empList)->freeCount = maxEmp;
...
}
To call this function you need to use the address-of operator &:
TREE *empList;
initializeTree(&empList);
Another alternative is to return the pointer:
TREE* initializeTree(void)
{
TREE* empList = malloc(sizeof(TREE));
...
return empList;
}
You are overwriting the value of empList in your function but it does not reach the caller. What you actually need to do is to pass in a pointer to a pointer of tree:
void initializeTree(TREE** empList)
{
*empList = (TREE *)malloc(sizeof(TREE));
[...]
}
You can also find more information (and other options) here.

C Function returning Array and pointer without a cast [duplicate]

This question already has answers here:
Declaring a C function to return an array
(5 answers)
Closed 9 years ago.
I got a problem with one of my final function. My goal is too treat a picture.
I declare in a header :
#define PICTURESIZE 1024
typedef unsigned char Picture[PICTURESIZE][PICTURESIZE];
typedef unsigned char LinearBlocPicture[PICTURESIZE*PICTURESIZE];
I include this header in an other file, where i got only one function :
LinearBlocPicture picture2BlocVector (Picture image){
LinearBlocPicture pictureModify;
int curseurLinearBlocPicture = 0;
unsigned char blocPixel[8][8];
unsigned char* bufferLinearBlocPicture;
int x,y,i,j,k;
for(y=0; y < 1024; y=y+8) {
for(x=0; x < 1024; x=x+8) {
for(j=0; j < 8; j++) {
for(i=0; i<8; i++) {
blocPixel[i][j] = image[x+i][y+j];
}
}
bufferLinearBlocPicture = bloc2Vector (blocPixel);
for (k=0; k<64; k++){
pictureModify[curseurLinearBlocPicture+k] = bufferLinearBlocPicture[k];
}
curseurLinearBlocPicture = curseurLinearBlocPicture + 64;
}
}
return pictureModify;
}
This function apply my treatment, the problem come from the return value, and what is expected to be return.
I got this when i try to compilate :
First line error: ‘picture2BlocVector’ declared as function returning an array
Application.c: In function ‘picture2BlocVector’:
Last line: warning: return makes integer from pointer without a cast
Last line: warning: function returns address of local variable
I don't understand why there is a problem for the return type, because i declare properly my type LinearBlocPicture. The pointer problem come from this line i think :
pictureModify[curseurLinearBlocPicture+k] = bufferLinearBlocPicture[k];
I'm not sure to be allowed to do this.
Thanks for your help.
In C, arrays are often "decayed" to pointer values, so when you return an array, you're essentially returning the address of its first element. In your sample code, you allocate pictureModify on a local stack, and attempt to return its address. When your function returns, all variables declared during its execution will be cleaned up -- this includes your local buffer.
To get around this you have a few options:
Use malloc() to allocate a block of memory, write your results to it and then return a pointer to it. When you do this, you need to make sure your calling code will call free() on it.
Allocate memory in your calling code, and pass a pointer to that buffer to picture2BlocVector. This way, you're localizing all memory management to one place. In this scenario, you can even create a local variable and pass its address.

Resources