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;
}
Related
This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 5 years ago.
I have written the following code:
#include <stdio.h>
#include <stdlib.h>
typedef struct _NeuralNetwork{
int input_rows;
int input_columns;
double **inputs;
}NeuralNetwork;
void main(){
// structure variable
NeuralNetwork *nn;
int count;
int i,j;
nn->input_rows = 2;
nn->input_columns = 3;
// create the array of double pointers using # of rows
nn->inputs = (double **)malloc(nn->input_rows * sizeof(double *));
// each pointer gets an array of double values
for (i=0; i<nn->input_rows; i++){
nn->inputs[i] = (double *)malloc(nn->input_columns * sizeof(double));
}
// assign values
count = 0;
for (i = 0; i < nn->input_rows ; i++)
for (j = 0; j < nn->input_columns; j++)
nn->inputs[i][j] = ++count;
// print those values
for (i = 0; i<nn->input_rows; i++)
for (j = 0; j < nn->input_columns; j++)
printf("%f ", nn->inputs[i][j]);
/* Code for further processing and free the
dynamically allocated memory*/
return;
}
When I compile this everything is okay. But after running it, I get a segmentation fault error:
Segmentation fault (core dumped)
I am not sure, where the mistake is. Can somebody help?
Note: When I use nn as structure variable instead of a structure, then everything is fine. But I want to use it as structure pointer and access the structure members via "->" and not via "." since I plan to pass nn as pointer to another function later.
Thank you in advance :)
The variable nn is a pointer, but that pointer is never initialized. You subsequently read and dereference that pointer using an operation such as nn->input_rows = 2;. This invokes undefined behavior.
In this particular case, nn likely contains some garbage value. By dereferencing that pointer value, you are attempting to read from memory you probably aren't allowed to. This is what causes the crash.
By defining nn as an instance of a struct instead of a pointer, as you said you tried, you avoid this issue. You can still however pass a pointer to other functions by taking the address of this variable and passing that to the function, i.e.:
NeuralNetwork nn;
...
myfunction(&nn)
First, do not use void main(), it's non-standard and would eventually cause problems. The right way is int main() or int main(int argc, char** argv). Remember to return a proper value at the end of the main function, possibly 0. Consult the reference here: main function
Second, if you use NeuralNetwork *nn; you must allocate some space for it in memory. It's a pointer to some memory address, if you don't allocate it who knows where it points. That's why you're getting the segfault. You must allocate memory for it in the following way:
NeuralNetwork *nn = malloc(sizeof(NeuralNetwork));
Then it should work properly.
This question already has answers here:
Returning an array using C
(8 answers)
Closed 5 years ago.
Basically what I'm doing is making a base program that I can build other programs off of, and I have a function (called input) that returns the characters collected from a user input. Right now, there's a 2 errors saying "return makes integer without a cast", and "function returns address of local variable". What I want it to be able to do is return a character array.
Here is the code:
#import <stdio.h>
void cls() {
system(cls);
}
char input() {
char X[0];
int Y = 0;
char Z;
while (1 == 1) {
Y = Y + 1; //increment step
Z = getch(); //get character input
if (Z == ';') {
break;
} //break if stop character is pushed
char Q[Y];
int a;
for (a = 0; a < Y; a = a + 1) {
Q[a] = X[a];
} //pass the items of X to the larger Q array
Q[Y] = Z; //add new value to Q at end of array
char X[Y];
int b;
for (b = 0; b < Y + 1; b = b + 1) {
X[a] = Q[a];
} //pass the items of Q back to a larger X
printf(X);
}
return X;
}
int main() {
while (1 == 1) {
//stuff will go here later
}
return 0;
}
Arrays are not first-class types in C, so you can't return them from functions, nor pass them as arguments to a function. You need to pass/return pointers instead. But as the pointers must point to something (to be useful), you need to keep track of who "owns" what the pointers point at -- who is responsible for allocation and freeing the memeory involved.
So that said, there are several ways you can manage passing and returning (pointers to) arrays.
You can have the caller allocate an array (either on the stack or the heap), and pass a pointer (and size) to that array to a function that will fill it in. The called function in this case doesn't have to worry about allocating and freeing the array, but does need to worry about not overflowing it.
You can have the callee allocate an array on the heap and return a pointer to the caller. You can't do this with callee stack allocated memory, as the all callee stack allocated memory is freed when the callee returns, so if you try to return a pointer to it, the pointer will be dangling. A heap allocated array avoids that problem, but means that the caller will need to free it, and has the additional difficulty that the caller doesn't know how large the allocated array is, unless you return a struct containing that info along with th pointer, or somehow communicate that info back to the caller.
You should do following:
errors saying "return makes integer without a cast"
Change return type of function input from char to char *.
errors saying "function returns address of local variable"
The memory returned my variable X should be allocated dynamically i.e. using calloc or malloc function. Because in provided code the memory hold my variable X is local and present in stack. So when function call returns from
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));
This question already has answers here:
Returning Arrays/Pointers from a function
(7 answers)
Closed 8 years ago.
I was trying to pass the array address from the function to the main function that's happening perfectly. But when I dereference the address in main(), I am getting junk values. I am guessing that the variables in the array_address memory lives only within the scope of the function. If this is the case, how do you return an array generated within a function to another function?
Here's my code:
int* letssee(int something)
{
int* array_address;
int a[10], i=0;
array_address = &a[0];
for (i; i<something;i++)
{
*(array_address+i) = i;
printf("\n%p, %d",(array_address+i), *(array_address+i));
}
return array_address;
}
int main()
{
int i= 5,j;
int* catch_address;
catch_address = letssee(i);
printf("\n");
for (j= 0; j<i; j++)
{
printf("%p, %d\n", (catch_address+j),*(catch_address+j));
}
return 0;
}
you can't return an array defined in a function as it is allocated on the stack and will disappear after the function has finished. Instead you allocate memory
int *array_address = malloc(sizeof(int) * 10);
however, you have to manage the memory, meaning you have to "free" it when you are finished with it, otherwise you will leak memory
The other approach is to pass the memory preallocated into a function (whether it be via malloc or the stack or global)
int* letsee(int something, int* array_address, int count);
if you simply make the array static, you are effectively making a global variable, multiple calls to the function will return the SAME address and may cause strange behaviour if you are expecting new arrays for each call.
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.