struct return error-C - c

this program is written in C
it supposed to get a two D array( matrixAdd) and scan it with scanMtx (the scanning function isn't here becuase the code isn't relevant)
the problem: the EDMtx function return the scanning matrix 1,1,1,,1,-8,1,,1,1,1
when it return back to main it is : 0,0,0,0,0,0,junk,junk,junk
it seems that there is a address error
what did i do wrong?
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
struct matrix
{
int* ptr;
int row;
int column;
};
matrix EDMtx();
void main( int argc, char* argv[])
{
int matrixAdd[5][5]={{1,1,1,3,4},{1,1,1,3,4},{1,1,1,3,4},{1,1,1,3,4},{1,1,1,3,4}};
matrix mtx;
matrix scanMtx;
mtx.ptr=&matrixAdd[0][0];
mtx.row=5;
mtx.column=5;
scanMtx= EDMtx();
// mtx= ScanM(mtx,1,1,scanMtx);- doesn't important to you.
getchar();
}
matrix EDMtx()
{
int matrx[3][3]={{1,1,1},{1,-8,1},{1,1,1}};
matrix Mtx;
Mtx.ptr=&matrx[0][0];
Mtx.row=3;
Mtx.column=3;
return Mtx;
}

The variables matrixAdd and matrx, and the memory they point to, have local scope only. If you want them to persist after returning from a function, either declare them static, or redesign your code logic. (e.g. by using malloc to allocate memory explicitly)

In EDMtx, Mtx.ptr is pointed to a stack variable. This is getting destroyed probably. If you want to exchange pointers to variables they must be on the heap

matrix EDMtx()
{
int matrx[3][3]={{1,1,1},{1,-8,1},{1,1,1}};
matrix Mtx;
Mtx.ptr=&matrx[0][0];
Mtx.row=3;
Mtx.column=3;
return Mtx;
}
matrx is a local variable. So, it goes out of scope when upon return of EDMtx(). And the Mtx.ptr has the reference of the local variable matrx. And so the pointer member of scnMtx, is getting garbage values upon dereferencing. Never return references of a local variable.

Related

Dynamic array in structs

I have a problem using dynamic memory in C.
I am creating a struct whose data is a number and a pointer to another struct (in short, an array of struct). The goal is for the parent struct to store an array of another struct using dynamic memory.
The problem I have is to access the cells of the created array, because I don't know if it's due to syntax issues (I'm new to C), or that I'm creating the array wrong, I can't modify the information contained in each cell of the contained array inside the parent struct. I can only modify by default the first cell.
This is my code, any idea or suggestion will be appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char string[64];
void* date;
void* colour;
} DataState;
typedef struct {
int number;
DataState* array;
} Book;
Book* makeBook (int number){
int a=5;
void* auxiliary=&a;
Book* book_A=(Book*)(malloc(sizeof(Book)));
book_A->number=number;
book_A->array=(DataState*)(malloc(number*sizeof(DataState))); //creating array of structs inside main struct.
//And what I want to do is something like this, modify the information contained in cells of the array of structs of the main struct.
book_A->array[3]->date=auxiliary;
return book_A;
}
From already thank you very much.
Here:
book_A->array[3]->date=auxiliary;
you assign a value of auxiliary to the 3rd element of an array, but auxiliary is defined as
void* auxiliary=&a;
while a is an automatic variable in your function.
Automatic variables disappear at the return from the function, hence the pointer assigned to book_A->array[3]->date becomes invalid as soon as the return is executed.
If you want the data saved in a to remain valid after makeBook returns, then you must allocate it in more persistent storage than automatic. You've essentially done this:
int* foo()
{
int a = 5;
// WRONG, cannot return the address of a local variable
return &a;
}
int main(void)
{
int* a_addr = foo();
// WRONG, invokes undefined behavior
printf("a = %d\n", *a_addr);
}
If you want a to persist outside of foo, a possible option is:
int* foo()
{
int* a = malloc(sizeof *a);
// always check the return value of malloc
if (a != NULL)
{
*a = 5;
}
// this is ok. `a` is still in automatic storage, but this _returns_ its
// value, which is a pointer to data _not_ in automatic storage.
return a;
}
int main(void)
{
int* a_addr = foo();
// still must check here, malloc in `foo` could have failed. Probably
// better to design an architecture where you only check validity once
if (a_addr != NULL)
{
printf("a = %d\n", *a_addr); // prints a = 5
// don't forget to `free(a_addr)` when you're done with it, or you can
// let the OS clean up the memory when the process exits.
}
else
{
// handle error how you want
fprintf(stderr, "Out of mem!\n");
}
return 0;
}

Why can we initialize inside a function and still use that value outside the function?

For example:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct {
int n;
double d;
} some_thing;
void alloc_and_init_some_thing(some_thing** s, int n, double d) {
some_thing si = { .n=n, .d=d };
*s = malloc(sizeof(**s));
memcpy(*s, &si, sizeof(**s));
}
void alloc_and_init_int(int **i) {
int j = 21;
*i = malloc(sizeof(**i));
memcpy(*i, &j, sizeof(**i));
}
int main() {
some_thing *s;
alloc_and_init_some_thing(&s, 41, 31);
printf("s->n=%d s->d=%f\n", s->n, s->d);
int *i;
alloc_and_init_int(&i);
printf("*i=%d\n", *i);
return 0;
}
I'm still learning C and the difference between the stack and the heap. When we declare and initialize the variable si in the function alloc_and_init_some_thing, doesn't this value exist on the stack? Hence it should get wiped out when the function finishes?
But I can see that that doesn't actually occur. Back in the main function, when we print s->n, we get the value 41.
Similarly, when we print the value for *i in the main function, it prints 21.
Why is that?
The line memcpy(*s, &si, sizeof(**s)); copies the the structure si on the stack into the heap allocated structure s, thus making it persist in memory as heap allocations can be accessed anywhere in the program. It's merely a pointer to an address in memory.
The same thing happens in the similar function.
You are right that the lifetime of "si" and "j" are limited to their respective functions and not available after the return from those functions. However, their contents have been replicated via malloc/memcpy prior to the return of the functions and the pointers to the replicas are stored in variables "s" and "i", which are still alive at the time of printing (or using) those replicas.

strange transition between integer and array

I have defined a global variable SEIS_FORMAT as an integer. But when I use it in the external function, I define it as an array SEIS_FORMAT[6] and use it as SEIS_FORMAT[0], as follows:
1.MAIN() code:
#include "head.h"
int SEIS_FORMAT=5; /*global variable*/
int main()
{
int a=2;
float b=3.5;
f1(&a, &b);
return 0;
}
2.function code: "f1.c"
#include "head.h"
void f1(int *a, float *b)
{
extern int SEIS_FORMAT[6]; //different from the main()
printf("a=%d,b=%f,c=%d\n",*a,*b,SEIS_FORMAT[0]); //notice the use of SEIS_FORMAT
}
Why can I always get the correct answer: a=2,b=3.500000,c=5?
The definitions of SEIS_FORMAT are equivalent to each other?
This is almost certainly undefined behavior, so anything is possible.
As to why it seems to work, the linker doesn't know anything about data types, it just knows that the name SEIS_FORMAT refers to a specific memory location. It's initialized by the main program as a single integer, but f1() then treats that memory location as the beginning of an array. Element 0 of the array corresponds to the integer that was initialized in the main program.

Change Array without returning it [C]

I just have a basic question concerning arrays in functions.
I am trying to change an array in a function without returning it.
I know how to do this for integers or doubles but i didn't know how to do this for arrays. So i experimented a little bit and now I am confused.
I have 2 variations of my code which i thought should do the same thing , but they don't. I pass the array b to the function Test. In the function I try to fill the array with the values 0, 1 ,2
#include <stdlib.h>
#include <stdio.h>
void Test(int * vector){
vector = malloc(3*sizeof(int));
int i;
for(i=0;i<3;i++){
*(vector+i)=i;
}
}
int main(){
int b[3];
Test(b);
printf("%i\n",b[0]);
printf("%i\n",b[1]);
printf("%i\n",b[2]);
return EXIT_SUCCESS;
}
This Version doesnt work, i don't get the expected result 0,1,2
This Code on the other hand does seem to work:
#include <stdlib.h>
#include <stdio.h>
void Test(int * vector){
int * b = malloc(3*sizeof(int));
int i;
for(i=0;i<3;i++){
*(b+i)=i;
*(vector+i) = *(b+i);
}
}
int main(){
int b[3];
Test(b);
printf("%i, ",b[0]);
printf("%i, ",b[1]);
printf("%i ",b[2]);
return EXIT_SUCCESS;
}
Can somebody explain to me why only the second one works?
Best Regards,
Rob
When you pass an array to a function, it decays into a pointer to the first element. That's what the function sees. But then you take the function parameter vector and overwrite it with dynamically allocated memory. Then you don't have access to the array you passed in. Additionally, you have a memory leak because you didn't free the allocated memory.
In the case of the second function you don't modify vector, so when you dereference the pointer you're changing b in main.
Also, instead of this:
*(vector+i)
Use this:
vector[i]
It's much clearer to the reader what it means.
test doesn't need to call malloc(). When you use an array as a function argument, it passes a pointer to the array. So you can simply write into vector[i] and it will modify the caller's array.
void Test(int * vector){
int i;
for(i=0;i<3;i++){
*(vector+i)=i;
}
}

C: dynamic declare array size

I have the following declaration inside a function
int f[20000]
I want the number 20000 to be dynamic, How can i declare such array in code?
To be more specific, I have the following code to calculate PI.
#include <stdlib.h>
#include <stdio.h>
#define BITS 2000
int a=10000,b,c=BITS*7/2,d,e,f[BITS*7/2+1],g;
int main()
{
for(;b-c;)
f[b++]=a/5;
for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a)
for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);
//getchar();
return 0;
}
I changed to
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
//
// .... omit some lines here
// read bits from user input at runtime
// say precision = 200
//
int a=10000,b,c=precision *7/2,d,e,f[precision *7/2+1],g;
for(;b-c;)
f[b++]=a/5;
for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a)
for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);
//getchar();
return 0;
}
It doesn't work, I googled then changed to
int a=10000,b,c=precision *7/2,d,e,g;
int *f=calloc(precision *7/2+1, sizeof(int));
It still doesn't work, I mean the program doesn't crash, the value it calculated is not correct. What's wrong? Thank you.
There are two ways to achieve what you want.
use dynamic memory allocation. malloc()/calloc()
use variable-length array (in c99)
That said, as pointed out by #user3386109, the problem in your second code snippet is use of uninitiated variable b. You may want to explicitly initialize the local variables before using their value.
You get a dynamically sized array by allocating on the heap using malloc (or calloc).
Replace
int f[20000];
with
int *f = (int *) malloc(20000 * sizeof(int) );
The difference is that global variables are guaranteed to be initialized to 0 (unless initialized to some other value). But local variables are garbage unless you initialize them. So the problem is that variable b starts out as garbage in the second snippet.
In the original code:
int a=10000,b;
int main(void)
{
}
a will start with the value 10000 because you initialized it, and b will start as 0 because it is an uninitialized global variable.
In the changed code:
int main(void)
{
int a=10000,b;
}
a will start with the value 10000 because you initialized it, and b will start as some random value (e.g. 0x5315fe) because it is an uninitialized local variable.
Replace int f[2000]
with
int *f = new int[2000];
then use the array as f[0] = 1, f[1] = 2 etc...
when finished free up memory with delete [] f;
the array size could be allocated by a variable
eg.
int x = 2000;
f = new int[x];

Resources