Array after initialise get BAD values [at C ] - c

first of all, I know that build array of elements without pointers it's bad coding but its part of the exercise which I can't change
edit :
typedef struct st
{
int id;
char *name;
int platforms;
} *Station;
i built an array of elements (structs) -
int num=X
Station statTable= malloc((num)*(sizeof(*statTable)));
and initialize it -
int i=0
while(i<num){
station=TS->stations+i*sizeof(*station);
station->name="blabla";
station->id=id;
i++
}
I check the array after initializing and its work, but after some iteration on the array -
int i=0;
while(i<num){
station=TS->stations+i*sizeof(*station);
printf("%d",station->id);
i++
}
when TS is big struct with pointer to station which is name is stations
I get a bad value ( print screen below)and it always in the second cell, someone has an idea why it happened?

Typedefing pointers isn't really good practice.
Bug in your code is in pointer arithmetics. More precisely here
station=TS->stations+i*sizeof(*station);
As we know adding 1 to pointer will move us in memory not one byte, but sizeof(typeItIsAppliedOn) bytes, in this case sizeof(Station) bytes.
So what you have written will move you outside of bounds pretty soon and as we know, accessing outside of bounds has undefined behavior.
This should fix it
station = TS->stations + i; // This will point to i-th station in memory
In general, you could use this semantics for better readbility
station = &TS->stations[i]; // Get an address of i-th element in array

Related

access to a member of a struct (pointer) with the use of double pointer

hey I am trying to create a program in which I am trying store elements from one array to another with the use of a pointer to pointer but the problem is that is caused undefined behavior I believe that the problem is that I do not pass the elements in members with a proper way
I know it is a vague way of doing this but It is in only for practising reasons
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct student{
char *name;
int *number;
}T;
int main(void) {
char array[10][100]={"araaaa","bbgt","gffkghgh"};
T arr[10][100];
T *p;
T **p1;
p=&arr[0][0];
p1=&p;
int i=0;
for(i = 0 ; i < 3 ; i++)
{ p=arr[i];
strcpy((*p1)->name,array[i]);
}
/*******print_elements*************/
for(i = 0 ; i < 3 ; i++)
{ p=arr[i];
printf("\n the elements are %s",(*p1)-> name);
}
return 0;
}
When you do this:
strcpy ((*p1)->name, array[i]);
(*p1)->name is an uninitialised pointer. What happens, therefore, is in the lap of the gods.
The easiest fix is to modify your student structure such that name is a buffer, rather than a pointer. At the same time, change number to an int, rather than a pointer to an int::
typedef struct student{
char name [100];
int number;
} T;
If you want to keep name as a pointer then you have to allocate some memory before you store your string in it. This should work:
(*p1)->name = strdup (array[i]);
Don't forget to free the memory when done.
T is made of of two pointers, this first one points to a string of characters in memory.
arr is a 2D array that is allocated to store a total of 1000 T structures.
arr[i] would reference a 1D array of T structures within arr
*p1 would essentially be arr[i], since dereferencing p1 gives you p, which was just set to arr[i]. So, that is not a pointer to a T structure, but to an array of T structures. Forcing the cast will likely give you a reference to the first T structure in that row, however.
->name This value is never set. You allocated an array, but "name" is a pointer to memory, not an array of characters, so '->name' is undefined.
I think you need to change arr to be a single dimension array. You aren't using 90% of it.
And, you need to initialize every T struct in that array. You can use malloc or strdup, and then remember to free them all. Or, set the struct to use an array instead.

Segmentation fault on reallocating of memory

I need to make a program for bakery managment, I've done structures and three pointer arrays that must contain pointers for object of these structures. But i can't make function to add new bakery because it needs dynamic memory allocating. I've tried to do this but it throws Segmentation Fault on realloc. I would be grateful for any advice how to properly reallocate memory for these arrays to add element. Also feel free to make comments about other errors in the code, I'm just learning.
typedef struct BakeryType {
char *name;
} BakeType;
typedef struct Bakerys {
char *name;
BakeType *type;
char *photo;
float weight;
int portions;
float price;
char *description;
} Bakery;
Bakery *bakeryList[0];
BakeType *bakeTypeList[0];
void addBakery() {
Bakery new;
*bakeryList = realloc(*bakeryList, (sizeof(bakeryList)/ sizeof(Bakery))+ 1);//Segmentation Fault
bakeryList[sizeof(bakeryList)/sizeof(Bakery)]=&new;
}
bakeryList is a zero-element array of pointers to Bakery. It has room for zero pointers.
Yet later you set the first element of this array (*bakeryList which is the same as bakeryList[0]) to whatever comes back from realloc. So you're overwriting something, and it probably goes downhill from there.
I think you want bakeryList to just be a pointer to Bakery. That's how dynamically-allocated arrays work in C: you define a pointer to the first element and use pointer math (e.g., bakeryList[5] or *(bakeryList + 5)) to access other elements.
Another issue is your use of sizeof(bakeryList). sizeof is an operator that's evaluated by the compiler. It doesn't change at runtime. sizeof(bakeryList) / sizeof(Bakery) will evaluate to zero because you defined bakeryList as a zero-element array. You need another variable to keep track of how many elements are actually in the array at runtime.
Something like this would work:
int bakeryCount = 0;
Bakery *bakeryList = NULL;
void addBakery() {
// Add one to the array.
bakeryCount++;
bakeryList = realloc(bakeryList, bakeryCount * sizeof (Bakery));
// Create a pointer to the new element at the end of the array.
Bakery *newBakery = bakeryList + bakeryCount - 1;
// Set all the fields. Note that they will probably contain
// garbage so you should set them all.
newBakery->name = ...
}

Access with a pointer on two structures with an array

I got another issue with my Code. I want to access on all 3 values with a simple pointer usage. But my Pointer jumps too far.
My Output is this:
Value is 1
Value is 4194432
Value is 2686824
I guess that my Problem is, that my pointer is from the wrong type. So pointer++ dont jump to the next array element. I really dont know, how i can solve this.
(It's only a simple example to reproduce my problem, so dont look for sense in doing this)
typedef struct _A {
int value;
}A;
typedef struct _B {
A array[10];
}B;
int main()
{
A atest;
B btest;
B *p=NULL;
btest.array[0].value=1;
btest.array[1].value=3;
btest.array[2].value=5;
p=malloc(10 * sizeof(btest));
p=&btest.array;
int i=0;
for(i=0;i<3;i++)
{
printf("\n%d. Value is %d\n",i+1,p++->array->value);
}
return 0;
}
Thx for reading and if something is missing in my explanation, then i will apologize and add it.
EDIT:
Additionally to Some Programmers Dude Sollution, i add a simple cast mechanic:
q=(A*) p;
q++;
p =(B*)q;
Thx for your help :)
These lines
p=malloc(10 * sizeof(btest));
p=&btest.array;
contains two problems. The first is that with the second assignment you lose the memory you allocated. It does not copy the contents of btest.array.
The second problem is that p is a pointer to B but &btest.array is a pointer to an array of ten A elements (its type is A (*)[10]). Those two are very different types.
If you want to copy btest into the memory allocated for p (which is a pointer to ten B structures which is a little overkill) do e.g.
p=malloc(sizeof *p);
memcpy(p, &btest, sizeof *p);
Then to the next problem:
p++->array->value
The p++ will make p point to the next element in the array pointed to by p, but that's wrong. You should loop over p->array instead like
p->array[i].value

Why does this C code work?

EDIT: Thank you very much for your responses. I understand this properly now!
I am trying to learn more on C pointers. Tinkering around, I am questioning the difference between two actions I am using.
This code seems to work at first glance, but I am not sure of what's the difference, and if any of these two approaches is wrong in some way.
I'd like to know what's the difference between the two pieces of code, when I should I pass the adress, and when a pointer to an array?
Is any of the pieces wrong? If so, what would be the proper way?
having a simple struct grid pretty much like struct grid { int val; } (for demonstration purposes)
First piece of code. Passing address of the pointer to the array.
void set (mygrid *grid, int foo){
grid->bar = foo; //should this be '*grid->bar?' But this seems to work properly.
}
void main(){
int i;
int* array;
int max = 24;
array = malloc(sizeof(grid) * max);
for(i = 0; i < max; i++){
set(&array[i], 0);
}
}
Second piece of code. I am not entirely sure why this works, but the compiler doesn't output any warning.
I am supposed to be passing the pointer to the start of the array like this?
void set(mygrid *grid, int foo){
int i; int max = 24; //so this example code compiles :P
for(i = 0; i < max; i++){
grid[i].bar = foo;
}
}
void main(){
int* array;
int max = 24;
array = malloc(sizeof(grid) * max);
set(array, 0); //Why not &array?
}
Passing an array decays into a pointer that points to the first member of the array, just like &array[0].
In your second example, array is just a pointer, and the return value from malloc is just the address of the start of the block of memory you get.
It doesn't have to be used for an array; it could be used for storage of an arbitrary sizeof(int) * max bytes of data. An array (in C) is really just a nice way of thinking about & working with a solid block of memory divided up into equal size portions.
Secondly, you should understand how my_array[i] works. All it does is take the address of where your block of array data starts (which is the actual value of my_array), and then look at what value is stored at a particular offset from there. Specifically, if my_array is of a (made up) type of WhatEver, then it will access the data from my_array + i*sizeof(WhatEver) to my_array + (i+1)*sizeof(WhatEver).
On a related note (since you're learning C), it's highly recommended to check that the return from malloc is not NULL before doing anything with it.
I'm no C guru but am also trying to improve my understanding so if this is incorrect, please leave a comment or edit my answer so I can learn from my mistakes :)
In your first piece of code
grid->bar is same as (*grid).bar
. and using name of an array refers to its base address. so writing array is equivalent &array[0]
&array[i] is equivalent to array+i
array[i] is equivalent to *(array +i)
In you second piece of code i dont understand why there is no error because in your function set you do not declare max and i dont see a global max variable too.
also in your second piece of code you use
set(array,0) because array is already an integer pointer(see the declaration int * array).As far as i understand the mygrid is not a struct but is an array of structs in the second example
In C, an array is pretty much the same as a pointer. For me this isn't so amazing, since it is one of the earlier programming languages I learned, but if you're coming from a high level language where an array is a different type of object, then it might come across as strange.

Coding problem using a 2-d array of structs inside another struct in C

I am working with a 2-dimensional array of structs which is a part of another struct. It's not something I've done a lot with so I'm having a problem. This function ends up failing after getting to the "test" for-loop near the end. It prints out one line correctly before it seg faults.
The parts of my code which read data into a dummy 2-d array of structs works just fine, so it must be my assigning array to be part of another struct (the imageStruct).
Any help would be greatly appreciated!
/*the structure of each pixel*/
typedef struct
{
int R,G,B;
}pixelStruct;
/*data for each image*/
typedef struct
{
int height;
int width;
pixelStruct *arr; /*pointer to 2-d array of pixels*/
} imageStruct;
imageStruct ReadImage(char * filename)
{
FILE *image=fopen(filename,"r");
imageStruct thisImage;
/*get header data from image*/
/*make a 2-d array of of pixels*/
pixelStruct imageArr[thisImage.height][thisImage.width];
/*Read in the image. */
/*I know this works because I after storing the image data in the
imageArr array, I printed each element from the array to the
screen.*/
/*so now I want to take the array called imageArr and put it in the
imageStruct called thisImage*/
thisImage.arr = malloc(sizeof(imageArr));
//allocate enough space in struct for the image array.
*thisImage.arr = *imageArr; /*put imageArr into the thisImage imagestruct*/
//test to see if assignment worked: (this is where it fails)
for (i = 0; i < thisImage.height; i++)
{
for (j = 0; j < thisImage.width; j++)
{
printf("\n%d: R: %d G: %d B: %d\n", i ,thisImage.arr[i][j].R,
thisImage.arr[i][j].G, thisImage.arr[i][j].B);
}
}
return thisImage;
}
(In case you are wondering why I am using a dummy array in the first place, well it's because when I started writing this code, I couldn't figure out how to do what I am trying to do now.)
EDIT: One person suggested that I didn't initialize my 2-d array correctly in the typedef for the imageStruct. Can anyone help me correct this if it is indeed the problem?
You seem to be able to create variable-length-arrays, so you're on a C99 system, or on a system that supports it. But not all compilers support those. If you want to use those, you don't need the arr pointer declaration in your struct. Assuming no variable-length-arrays, let's look at the relevant parts of your code:
/*data for each image*/
typedef struct
{
int height;
int width;
pixelStruct *arr; /*pointer to 2-d array of pixels*/
} imageStruct;
arr is a pointer to pixelStruct, and not to a 2-d array of pixels. Sure, you can use arr to access such an array, but the comment is misleading, and it hints at a misunderstanding. If you really wish to declare such a variable, you would do something like:
pixelStruct (*arr)[2][3];
and arr would be a pointer to an "array 2 of array 3 of pixelStruct", which means that arr points to a 2-d array. This isn't really what you want. To be fair, this isn't what you declare, so all is good. But your comment suggests a misunderstanding of pointers in C, and that is manifested later in your code.
At this point, you will do well to read a good introduction to arrays and pointers in C, and a really nice one is C For Smarties: Arrays and Pointers by Chris Torek. In particular, please make sure you understand the first diagram on the page and everything in the definition of the function f there.
Since you want to be able to index arr in a natural way using "column" and "row" indices, I suggest you declare arr as a pointer to pointer. So your structure becomes:
/* data for each image */
typedef struct
{
int height;
int width;
pixelStruct **arr; /* Image data of height*width dimensions */
} imageStruct;
Then in your ReadImage function, you allocate memory you need:
int i;
thisImage.arr = malloc(thisImage.height * sizeof *thisImage.arr);
for (i=0; i < thisImage.height; ++i)
thisImage.arr[i] = malloc(thisImage.width * sizeof *thisImage.arr[i]);
Note that for clarity, I haven't done any error-checking on malloc. In practice, you should check if malloc returned NULL and take appropriate measures.
Assuming all the memory allocation succeeded, you can now read your image in thisImage.arr (just like you were doing for imageArr in your original function).
Once you're done with thisImage.arr, make sure to free it:
for (i=0; i < thisImage.height; ++i)
free(thisImage.arr[i]);
free(thisImage.arr);
In practice, you will want to wrap the allocation and deallocation parts above in their respective functions that allocate and free the arr object, and take care of error-checking.
I don't think sizeof imageArr works as you expect it to when you're using runtime-sized arrays. Which, btw, are a sort of "niche" C99 feature. You should add some printouts of crucial values, such as that sizeof to see if it does what you think.
Clearer would be to use explicit allocation of the array:
thisImage.arr = malloc(thisImage.width * thisImage.height * sizeof *thisImage.arr);
I also think that it's hard (if even possible) to implement a "true" 2D array like this. I would recommend just doing the address computation yourself, i.e. accessing a pixel like this:
unsigned int x = 3, y = 1; // Assume image is larger.
print("pixel at (%d,%d) is r=%d g=%d b=%d\n", x, y, thisImage.arr[y * thisImage.width + x]);
I don't see how the required dimension information can be associated with an array at run-time; I don't think that's possible.
height and width are undefined; you might want to initialise them first, as in
thisImage.height = 10; thisImage.width = 20;
also,
what is colorRGB?
*thisImage.arr = *imageArr; /*put imageArr into the thisImage imagestruct*
This won't work. You have to declare arr as colorRGB **, allocate it accordingly, etc.
it looks like you are trying to copy array by assignment.
You cannot use simple assignment operator to do that, you have to use some function to copy things, for example memcpy.
*thisImage.arr = *imageArr;
thisimage.arr[0] = imagearr[0];
The above statements are doing the same thing.
However this is not most likely what causes the memory corruption
since you are working with two dimensional arrays, do make sure you initialize them correctly.
Looking at the code, should not even compile: the array is declared as one-dimensional in your image structure but you refer to as two-dimensional?

Resources