Structure variable has Pointer variable in c - c

I want to know why structure variable passes pointer variable to create memory.
what happens if we do box *boxes = malloc(n * sizeof(box));
Then we pass address to scanf function. Pointer actually stores the address. Then why we pass "&" of scanf to pointer ?
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &boxes[i].length, &boxes[i].width, &boxes[i].height);
}
#include <stdio.h>
#include <stdlib.h>
#define MAX_HEIGHT 41
struct box
{
/**
* Define three fields of type int: length, width and height
*/
int length,width,height;
};
typedef struct box box;
int get_volume(box b) {
/**
* Return the volume of the box
*/
return b.length*b.width*b.height;
}
int is_lower_than_max_height(box b) {
/**
* Return 1 if the box's height is lower than MAX_HEIGHT and 0 otherwise
*/
return b.height < 41 ? 1 : 0;
}
int main()
{
int n;
scanf("%d", &n);
box *boxes = malloc(n * sizeof(box));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &boxes[i].length, &boxes[i].width, &boxes[i].height);
}
for (int i = 0; i < n; i++) {
if (is_lower_than_max_height(boxes[i])) {
printf("%d\n", get_volume(boxes[i]));
}
}
return 0;
}
When I tried running the sizeof struct,I got the sizeof Struct box it was 12.
Say n = 5, Then what will be the memory space?
memory = 12 * 5 ?

malloc() is used to allocate dynamic and variable sized memory. So we use this to create an array of n structures.
You need & because scanf() needs the address of the variable to store the input data to. b is a pointer, but b[i].length is just an ordinary structure member accessed by dereferencing that pointer. You need to get its address to pass to scanf().

box *boxes = malloc(n * sizeof(box));
Allocates enough space for n instances of box on the heap and returns a pointer to it
scanf("%d%d%d", &boxes[i].length///
is passing the address of boxes[i].length to scanf. Scanf needs to write there so its needs the address. Its just like
scanf("%d", &n);
that you did earlier
sizeof(struct box)
equaling 12 is fine. It has 3, 4 byte integers. You wont always get it that simply , the compiler might pad the structure to align things on 2, 4 or 8 byte boundaries, this is why sizeof exists
Say n = 5, Then what will be the memory space? memory = 12 * 5 ?
yes

Related

Structure's int field gets modified after malloc() on the same structure's int*

#define MAX_NUM_STACKS_ALLOWED 10
#define MAX_PLATES_PER_STACK 5
#define NEW_STACKS_CREATION_INC 2
typedef struct stackOfPlates {
int currentStackIndex;
int currentStackTop[MAX_NUM_STACKS_ALLOWED];
int currentMaxStacks;
int **stackOfPlatesArray;
} stackOfPlates_t;
stackOfPlates_t *stackOfPlates_Init(void) {
stackOfPlates_t *stackOfPlates = (stackOfPlates_t *)malloc(sizeof(stackOfPlates));
stackOfPlates->stackOfPlatesArray = (int **)malloc(NEW_STACKS_CREATION_INC * sizeof(int *));
stackOfPlates->currentStackIndex = 0;
stackOfPlates->currentMaxStacks = NEW_STACKS_CREATION_INC;
int i;
for (i = 0; i < stackOfPlates->currentMaxStacks; i++) {
stackOfPlates->stackOfPlatesArray[i] = (int *)malloc(MAX_PLATES_PER_STACK * sizeof(int));
printf("%d\n", stackOfPlates->currentMaxStacks);
}
for (i = 0; i < MAX_NUM_STACKS_ALLOWED; i++) {
stackOfPlates->currentStackTop[i] = -1;
}
return stackOfPlates;
}
void main()
{
stackOfPlates_t *stackOfPlatesA;
stackOfPlatesA = stackOfPlates_Init();
}
The output of the above code is:
2 (expected),
0 (not expected, not sure how this field gets modified)
I'm trying to malloc the 2D array (stackOfPlates->stackOfPlatesArray). After allocating memory for the NEW_STACKS_CREATION_INC number of stacks, I allocate memory for MAX_PLATES_PER_STACK for every stack. During this operation, I find that my stackOfPlates->currentMaxStacks gets modified to 0.
Could someone please explain why?
In your code
malloc(sizeof(stackOfPlates));
should be
malloc(sizeof(*stackOfPlates));
As you want to allocate memory for the structure type not the pointer to structure type.
That said, see this: Do I cast the result of malloc?

How to use Malloc pointers in comparison to array in C

I created a struct called PLAYER and I want to create an list that stores the pointers to the PLAYER object.
If I want to accomplish it with
PLAYER **ptr = malloc(10*sizeof(PLAYER *));
How can I assign the pointers to each index? I tried:
PLAYER *a;
PLAYER *b;
ptr[0] = a;
ptr[1] = b;
1.This seems to work. Can I get some explanation on the memory address behind it?
I also tried:
ptr = a;
//increase the address and assign b
ptr += sizeof(PLAYER *);
ptr = b;
2.This does not work correctly I think. Can I see a correct way of assign the list without using the [] brackets?
3.If I allocate only one entry's size and assign multiple ones:
PLAYER **ptr = malloc(1*sizeof(PLAYER *));
ptr[0] = a;
ptr[1] = b;
I can get these PLAYER object by using ptr[0] ptr[1], but will this cause any problems like overwrite other memories?
4.If I use [] brackets, do I need to malloc at each index in order to use it?
PLAYER *ptr[10];
for(int i = 0; i < 10; i++)
ptr[i] = malloc(sizeof(PLAYER *));
5.Do I need to free an array after using it? such as:
char ptr[10] = "abc";
//do something with ptr
free(ptr);
char *ptr2[10] = {"123", "abc"};
free(ptr2);
Any help would be much appreciated!
If you have a PLAYER **ptr = malloc(10*sizeof(PLAYER *));
That means you have to malloc for every ptr[i] = malloc(sizeof(PLAYER));
Accessing the array at indexes would be ptr[i]->somevalue
NOTE: if you have pointers inside the struct you need to allocate for those as well!!
Freeing your memory would be:
for(int i = 0; i<10;i++){
free(ptr[i]->anyAllocatedPointersInside);
free(ptr[i]);
}
free(ptr);
SPECIFICALLY IN THAT ORDER
If you update the post with the full struct I can update mine to more accurately help you.
When in doubt, think of malloc() allocations in these terms: it allocates raw memory, and it doesn't know anything about your structs!
When you think in these terms, you'll get it right.
Let's try to answer to your questions:
You are basically instancing within the stack a pointer, with any content into it, just as int hello;. That integer can contain anything, because you don't set it as in int hello = 2;. The same thing is happening with your pointers: int * hello; will be a pointer (to an integer) that can contain any address. Hence, if you dereference a pointer like that, your chances to get caught into SIGSEGV are not low.
Then, once you have created those pointers that can be anything, you're assigning their address to the pointer of pointers array you've allocated. Don't do that.
That doesn't work correctly, because if you have an array of pointers to a given type, you can simply increment with += n, the compiler will calculate the appropriate "sizeof(type_you're-pointing_to)" and will add that automatically. This is the main purpose of declaring a pointer to a given type.
You're effectively overwriting other memory.
Brackets are just pointer dereferencing: *ptr+n same as ptr[n].
You need to free each line, and then the array of pointers of pointers.
Basically every pointer you get with malloc(), you have to free it with free(). DO NOT call free() to any other pointers that hasn't been spit out from malloc().
Let me show you some code I have just written to show you better:
#include <stdlib.h>
#include <stdio.h>
#include <string.h> // for memset
#define N_POINTERS 4
#define M_PLAYERS_PER_LINE 3
struct PLAYER
{
int id;
int score;
int age;
};
int
main()
{
// Allocate the array of pointers, big enough to old N pointers.
struct PLAYER ** pointers = malloc(N_POINTERS*sizeof(struct PLAYER*));
// Always better zeroize pointers arrays.
memset(pointers, 0, N_POINTERS*sizeof(struct PLAYER *));
// Allocate each line of M `PLAYER` structs.
// Basically we allocate N chunks of memory big enough to contain M PLAYER structs one next each other.
// What we get is something like this:
//
// pointer pointers PLAYER lines
// of pointers array
// [addrP] -> [addr0] -> [PLAYER0 PLAYER1 PLAYER2] .. M
// [addr1] -> [PLAYER0 PLAYER1 PLAYER2] .. M
// ...N
//
int id = 0;
for (int i = 0; i < N_POINTERS; ++i)
{
pointers[i] = malloc(M_PLAYERS_PER_LINE*sizeof(struct PLAYER));
// Set the data you want to the structs.
for (int k = 0; k < M_PLAYERS_PER_LINE; ++k)
{
pointers[i][k].id = id++;
pointers[i][k].score = 123 + k;
pointers[i][k].age = 33 + i;
}
}
// Print data.
// Here we use a single PLAYER pointer that will
// traverse the entire PLAYER matrix.
struct PLAYER * player;
for (int i = 0; i < N_POINTERS; ++i)
{
for (int k = 0; k < M_PLAYERS_PER_LINE; ++k)
{
// Assign the current PLAYER to our pointer.
player = pointers[i] + k;
// Print PLAYER data, by reading the pointed struct.
printf("Player: #%i age:%i score:%d\n", player->id, player->age, player->score);
}
}
// Deallocate!
for (int i = 0; i < N_POINTERS; ++i)
{
// Deallocate each line chunk.
free(pointers[i]);
}
// Deallocate the array of pointers.
free(pointers);
return 0;
}
As a bonus track, if you need to allocate a matrix of M*N PLAYER structs, you should also look at this code, that will allocate M*N PLAYER structs into one unique memory block, one next each other, which is much more easier to manage, as you can see by the code itself:
#include <stdlib.h>
#include <stdio.h>
#define LINES 4
#define COLUMNS 3
#define GET_ARRAY_POS(lin, col) (col+(lin*COLUMNS))
struct PLAYER
{
int id;
int score;
int age;
};
int
main()
{
// Allocate a *FLAT* array of PLAYER structs, big enough to
// contain N*M PLAYER structs, one next each other.
struct PLAYER * array = malloc(LINES*COLUMNS*sizeof(struct PLAYER));
// Set the data you want to the structs.
int id = 0;
for (int lin = 0; lin < LINES; ++lin)
{
for (int col = 0; col < COLUMNS; ++col)
{
int pos = GET_ARRAY_POS(lin, col);
array[pos].id = id++;
array[pos].score = 123 + col;
array[pos].age = 33 + lin;
}
}
// Print data.
// Here we use a single PLAYER pointer that will
// traverse the entire PLAYER matrix.
for (int i = 0; i < (LINES*COLUMNS); ++i)
{
// Print PLAYER data, by reading the pointed struct.
printf("Player: #%i age:%i score:%d\n", array[i].id, array[i].age, array[i].score);
}
// Deallocate!
free(array);
return 0;
}
Enjoy! ^_^

Strange behavior while filling dinamically allocated 2D char array in C

I need to create a program that plays the game Hex on a 14x14 board.
So I created, allocated and filled the board with '-' (our pattern for empty spaces).
When I try to print the board's coordinates, I don't always get '-' but some random characters.
Also, if I try to printf array[i][j] on the createBoard function after the line "board[i][j] = '-';" I get a segmentation fault right after it prints tab[8][0].
What is causing this and how can I fix it?
My code:
#include <stdio.h>
#include <stdlib.h>
char **createBoard()
{
/*Allocates a 14x14 matrix and fills it
*with '-' to create the board.*/
int i, j;
char **board;
board = malloc(14);
if (!board) exit(1);
for (i = 0; i < 14; i++){
board[i] = malloc(14);
if (!board[i]) exit (1);
for (j = 0; j < 14; j++)
board[i][j] = '-';
}
return board;
}
int main()
{
int i, j;
char **board = createBoard();
for (i = 0; i < 14; i++)
for (j = 0; j < 14; j++)
printf("tab[%d][%d]: %c\n",i, j, board[i][j]);
return 0;
}
For starters it is not clear why you don't want to declare an array instead of allocating dynamically numerous one-dimensional arrays.
As for the code then this memory allocation
board = malloc(14);
is invalid. You have to write
board = malloc( 14 * sizeof( char * ));
Also you should free all the allocated memory in the reverse order relative to its allocation before the program ends.
Take into account that it is always better to use named constants instead of magic numbers. At least you could write either
#define N 14
before main
or
const int N = 14.
and use the variable N everywhere where you are using magic number 14.
By the way according to the C Standard function main without parameters shall be declared like
int main( void )
The variable *board is a pointer, but you only allocate one byte for each array element, which should be
#define DIM 14
board = malloc(DIM * sizeof *board);
Following that up with the second allocation
board[i] = malloc(DIM * sizeof **board);
This also allows (a) that the dimension 14 is hard coded in only one place in the program and (b) the allocation will survive if you later make the board's element a different type, for example a struct, as the program develops.

Size of matrix not evaluating correctly [duplicate]

This question already has answers here:
Using sizeof with a dynamically allocated array
(5 answers)
Closed 7 years ago.
I'm working on a C program that involves generating adjacency matrices of random graphs. Here is a snippet of the source code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "test.h"
int main()
{
int **A = create_matrix(4, 3);
destory_matrix(A);
return 0;
}
int** create_matrix(int size, int seed)
{
// Allocate space for matrix
int **A = malloc(size * size * sizeof(int));
for (int r = 0; r < size; r++) {
A[r] = malloc(size * sizeof(int));
}
// Fill entries
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
A[i][j] = seed * (i + 1) * (j + 1);
}
}
return A;
}
void destory_matrix(int **A)
{
int size = sizeof(A[0]) / sizeof(int);
for (int r = 0; r < size; r++) {
free(A[r])
}
free(A);
}
This portion of the code is responsible for creating the matrix (the create_matrix() function) and free'ing memory (destroy_matrix()). I'm looking at destroy_matrix(), and noticed that when a 4x4 matrix is passed in, the variable size evaluated to 2, rather than 4. Could anyone explain why this happens?
I think you have a basic misunderstanding of the sizeof operator. It can't, in general, be used to get the size of dynamically allocated compound objects. The sizeof operator returns to you the size based on the type of the operand. In your case, the type of the operand is int *. I guess you are running on a 64 bit system. So the sizeof any pointer is 8. Hence your size variable will always be 2 no matter the size of your matrix.
The sizeof operator applied to a pointer returns the size of the pointer type, not the size of any allocated memory it happens to point to.
This is one of the key differences between an array type and a pointer type in C (note: arrays can decay to pointers). sizeof applied to an statically specified array type (e.g. int foo[n];) will get you the size of the array in bytes.
Since your word size is probably 8 bytes (64-bit), the size of a pointer will be 8 bytes, and if sizeof(int) is 4 bytes (32-bits), you have 8 / 4 = 2;
You need to consider some other way to store the dimensions of your matrices if you need runtime-sized heap-allocated matrices, e.g. a struct that stores the dimensions and a pointer to the allocated memory. It would be better to avoid possible heap-fragmentation altogether, though.
Try this if you have C99:
int n = 4, m = 5;
int (*A)[n] = malloc(m * sizeof A[0]));
free(A);
This allocates an m length array of int[n] as a single block, so you can do size_t n = sizeof(A)/sizeof(A[0]); to get one dimension(n) but you'll need to store m if you want to iterate correctly.

C: Dynamic memory allocation using pointer to array with fixed number of chars

so I guess this is more a stylistic question.
I need to write into a dynamic array of elements with the size of 3 bytes. (bitmap with pixel size of 24bpp)
So, every element would have to be a char[3].
If I want to avoid using a struct pixel{ char R, char G, char B}, to avoid the usage of preprocessor statements, is it possible to write it as
char* pixel[3]
and allocate in steps of 3*sizeof(char)?
To account for height and width, I would need a char** pixel[3], and having to allocate in single char steps would make that a char*** pixel.
So I guess I'm looking for a way to avoid using a pointer-pointer-pointer.
Thanks!
Do you mean N blocks of 3 unsigned char' s [0...255]?
Note the difference:
unsigned char *pixel[3] -> array of pointers to char
Vs
unsigned char (*pixel)[3] -> pointer to array of chars
#include <stdio.h>
#include <stdlib.h>
#define N 4
int main(void)
{
unsigned char (*pixel)[3];
pixel = malloc(sizeof(*pixel) * N);
pixel[0][0] = 0;
pixel[0][1] = 128;
pixel[0][2] = 255;
/* ... */
pixel[3][0] = 0;
pixel[3][1] = 128;
pixel[3][2] = 255;
printf("R:%d G:%d B:%d\n", pixel[0][0], pixel[0][1], pixel[0][2]);
free(pixel);
return 0;
}
If you don't know N before hand replace malloc with realloc
You can simulate this using a 1D array. Say you want to allocate a wxh rectangle of pixels. You could write.
char *pixels = (char *) malloc(w*h*3*sizeof(char));
Now the 3 color bytes appear contiguous in memory and you can access any cell using some arithmetic
You can get/set the color channels at cell (i,j) by defining the macros:
#define r(p, i, j) ((p)[(3*((w)*(i)+(j)))])
#define g(p, i, j) ((p)[(3*((w)*(i)+(j)) + 1)])
#define b(p, i, j) ((p)[(3*((w)*(i)+(j)) + 2)])
Call looks like r(pixels, 0, 1).
If you don't want structs, you can't avoid writing char***.
But you can use a type, to make it more stylish.
So the best solution matching your requirements seems to be:
#include <stdlib.h>
typedef char*** pixelmap_t;
int main() {
int channels = 3, width = 10, height = 10;
pixelmap_t test = malloc(width*height*channels);
int x = 1, y = 2, channel = 0;
test[x][y][channel] = 3;
free(test);
return 0;
}
It seems, I totally fucked up. I confused the following two things:
When you declare a static 3D-Array pixels[100][100][3], then the type is not char***. It is a one-dimensional array of 300 consecutive items in memory.
When you declare a char*** and assign 300 items in memory, then dereferencing all of the dimensions with the pixels[x][y][z] syntax results in derefrencing the first dimension and interpreting the value in memory as pointer and derefrencing this pointer instead of computing the correct offset in a 3D-Array.
That means, I overlooked, that the array[x][y][z] accessor syntax has two different semantics. The first I would call the array ([x][y][z]) semantic for 3D-arrays and the second I would call the ((array[x])[y])[z] semantics for char*** (I used the brackets for emphasizing).
This code snipped compiles and works (tested it) - but does not use heap memory.
For heap memory I don't know an other solution than those, which have been posted already (malloc(width*height*channels) and access with pixels[c + channels*(y + x*height)]).
#include <stdlib.h>
#include <stdio.h>
int main() {
int channels = 3, width = 10, height = 10;
char test[width][height][channels];
char *ptr = (char*) test;
for (int i = 0 ; i < channels * width * height ; i++) {
ptr[i] = (char) (i % 255);
}
for (int x = 0 ; x < width ; x++) {
for (int y = 0 ; y < height ; y++) {
for (int c = 0 ; c < channels ; c++) {
int d = (int) test[x][y][c];
printf("%d %d - %d : %d\n", x, y, c, d);
}
}
}
return 0;
}

Resources