How to realloc 2d struct pointer with different size - c

I want to realloc 2d pointer array. It must be dynamic as follows ascii
+=====+==============+==============+==============+==============+======+
| | [0] | [1] | [2] | [3] | [..] |
+=====+==============+==============+==============+==============+======+
| [0] | 'a' | 'b' | 'c' | 'd' | |
+-----+--------------+--------------+--------------+--------------+------+
| [1] | object[0][0] | object[1][0] | object[2][0] | object[3][0] | |
+-----+--------------+--------------+--------------+--------------+------+
| [2] | object[0][1] | object[1][1] | object[2][1] | object[3][1] | |
+-----+--------------+--------------+--------------+--------------+------+
| [3] | object[0][2] | object[1][2] | object[2][2] | | |
+-----+--------------+--------------+--------------+--------------+------+
| [4] | object[0][3] | | object[2][3] | | |
+-----+--------------+--------------+--------------+--------------+------+
| [5] | object[0][4] | | | | |
+-----+--------------+--------------+--------------+--------------+------+
| [6] | object[0][5] | | | | |
+-----+--------------+--------------+--------------+--------------+------+
In this table every cols size is different. How can i do this with 2d struct. I allocated matrix with malloc. But i want to realloc second index. Like this matrix[25][n]. N must be realloc for every column with different size. But it must be on runtime
Code :
#include <stdio.h>
#include <stdlib.h>
typedef struct{
char word[20];
}Dictionary;
Dictionary **object;
void initializeDictionary()
{
// Create matrix [29][1]
object=(Dictionary**)malloc(29 * sizeof(Dictionary*));
object[0]=(Dictionary*)malloc(1*sizeof(Dictionary));
}

With pointers this comes naturally. In your code you have a Dictionary** which indeed is a pointer to pointer to Dictionary. But you can see it an array of Dictionary* in which each pointer points to a different sized array of Dictionary objects.
Dictionary** objects;
const int COLUMNS = 29;
objects = malloc(COLUMNS * sizeof(Dictionary*));
objects[0] = malloc(2 * sizeof(Dictionary)); // first column 2 elements
objects[1] = malloc(3 * sizeof(Dictionary)); // second column 3 elements
// ...
for (int i = 0; i < COLUMNS; ++i)
free(objects[i]);
free(objects);

Related

What happens when I add character array with unsigned long in c?

#include <stdio.h>
#include<string.h>
void double_string(char ary[])
{
char *start = ary;
// dont exactly know what is happening here nothing is getting printed when consoled
char *end = ary + strlen(ary);
char *org = end;
while(start<org)
{
*end = *start;
start++;
end++;
}
*end = '\0';
}
int main(void) {
char word[255] = {"TACsasasa"};
double_string(word);
printf("%s",word);
return 0;
}
I am unable to understand what is getting stored in character array "*end", I tried printing it but I am not getting any output printed..
char *end = ary + strlen(ary);
This line of code is taking the starting address of the char array in memory, adding the number of bytes inside the array, returned by strlen(), and essentially moving the pointer to the end. The end of the array is the null terminator. Printing that will show nothing as it takes it as an empty string.
Adding an unsigned int (or even a signed int!) is known as pointer arithmetic. It's legal and quite common in C code. You do have to be very careful about going out of the bounds of your memory buffer, though, or you will experience undefined behavior. This is bad. Fortunately, this code appears to be quite well behaved as long as the original string is less than half the length of its memory buffer.
Allow me to try some ASCII art to see if I can make clear what's going on in the double_string function. It starts with this:
char *start = ary;
char *end = ary + strlen(ary);
char *org = end;
At this point, your pointers look like this:
start end
| |
| org
| |
v V
----------------------------------------------------------------------------------
ary | T | A | C | s | a | s | a | s | a |\0 | | | | | | | | | | | ...
----------------------------------------------------------------------------------
Then we have the loop.
while(start<org)
{
*end = *start;
start++;
end++;
}
After the first loop iteration, it looks like this:
start end
| |
| org |
| | |
v V V
----------------------------------------------------------------------------------
ary | T | A | C | s | a | s | a | s | a | T | | | | | | | | | | | ...
----------------------------------------------------------------------------------
Second iteration:
start end
| |
| org |
| | |
v V V
----------------------------------------------------------------------------------
ary | T | A | C | s | a | s | a | s | a | T | A | | | | | | | | | | ...
----------------------------------------------------------------------------------
And so on. The loop continues as long as start is less than (to the left of, in my illustration) org:
start end
| |
org |
| |
V V
----------------------------------------------------------------------------------
ary | T | A | C | s | a | s | a | s | a | T | A | C | s | a | s | a | s | a | | | ...
----------------------------------------------------------------------------------
Now start<org is no longer true, because they're equal. They point to the same location. The loop terminates. All that's left to do is terminate the string with *end = '\0';:
start end
| |
org |
| |
V V
----------------------------------------------------------------------------------
ary | T | A | C | s | a | s | a | s | a | T | A | C | s | a | s | a | s | a |\0 | | ...
----------------------------------------------------------------------------------

Can't pass multidimensional array to structure

typedef struct arg_struct {
struct GPU_FFT *fft;
struct GPU_FFT_COMPLEX *base;
float **input;
float *output;
int number;
} arg_struct;
...
arguments[0].input = **Queue;
arguments[1].input = *(*(Queue)+QueueSize[0]);
My multidimensional array is Queue[2][1025]. I am trying to pass Queue[0][0] and Queue[1][0] into my arguments structure. It gives me "error: incompatible types when assigning to type ‘float **’ from type ‘float’" error. As a rookie programmer, I've tried so many variations but still couldn't figure out how to pass them.
By the way, QueueSize[0] is an integer which has value of 1025.
You can solve your problem very easily, by making the input member a simple pointer:
float *input;
Then you can make each pointer point to the corresponding array of Queue:
arguments[0].input = Queue[0];
arguments[1].input = Queue[1];
Be careful though, the lifetime of Queue must be at least as long as the lifetime of arguments. If Queue goes out of scope then the pointers will be stray, and can no longer be used. If Queue can go out of scope then you need to create full arrays of (or allocate memory for) the input member, and copy the contents into that memory.
There is big difference between 2d array and pointer to pointer.
In your struct is pointer to pointer, so you have to init it like
arguments[0].input = malloc(sizeof(float *) * num_of_rows);
for (int i = 0; i < num_of_rows; i++)
{
arguments[0].input[i] = malloc(sizeof(float) * num_of_cols);
}
Dont forget to free all the allocated memory. You can use valgrind for checking memory leaks.
2D array is sequence of bytes in memory
0 1 2 3
+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 // begins on address 1000
+---+---+---+---+
| 0 | 0 | 0 | 0 | 1 // begins on address 1004
+---+---+---+---+
| 0 | 0 | 0 | 0 | 2 // begins on address 1008
+---+---+---+---+
| 0 | 0 | 0 | 0 | 3 // begins on address 1012
+---+---+---+---+
while array of pointers, where every pointer can point to another part of memory
0 1 2 3
+---+---+---+---+
| * | * | * | * |
+---+---+---+---+
| | | |
| | | | 0 1 2 3
| | | | +---+---+---+---+
| | | -> | 0 | 0 | 0 | 0 | // begins on address 1000
| | | +---+---+---+---+
| | -----> | 0 | 0 | 0 | 0 | // begins on address 2
| | +---+---+---+---+
| ---------> | 0 | 0 | 0 | 0 | // begins on address 3045
| +---+---+---+---+
-------------> | 0 | 0 | 0 | 0 | // begins on address 128
+---+---+---+---+

How memory is allocated when we use malloc to create 2-dimensional array?

I want to create an integer array[5][10] using malloc(). The difference between memory address of array[0] and array[1] is showing 8. Why?
#include <stdio.h>
#include <stdlib.h>
int main() {
int *b[5];
for (int loop = 0; loop < 5; loop++)
b[loop] = (int*)malloc(10 * sizeof(int));
printf("b=%u \n", b);
printf("(b+1)=%u \n", (b + 1));
printf("(b+2)=%u \n", (b + 2));
}
The output is:
b=2151122304
(b+1)=2151122312
(b+2)=2151122320
The difference between memory address of array[0] and array[1] is showing 8. Why?
That's because sizeof of a pointer on your platform is 8.
BTW, use of %u to print a pointer leads to undefined behavior. Use %p instead.
printf("(b+1)=%p \n",(b+1));
printf("(b+2)=%p \n",(b+2));
Difference between array of pointers and a 2D array
When you use:
int *b[5];
The memory used for b is:
&b[0] &b[1] &b[2]
| | |
v v v
+--------+--------+--------+
| b[0] | b[1] | b[2] |
+--------+--------+--------+
(b+1) is the same as &b[1]
(b+2) is the same as &b[2]
Hence, the difference between (b+2) and (b+1) is the size of a pointer.
When you use:
int b[5][10];
The memory used for b is:
&b[0][0] &b[1][0] &b[2][0]
| | |
v v v
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ ...
| | | | | | | | | | | | | | | | | | | | | ...
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ ...
(b+1) is the same as &b[1], The value of that pointer is the same as the value of &b[1][0] even though they are pointers to different types.
(b+2) is the same as &b[2], The value of that pointer is the same as the value of &b[2][0]
Hence, the difference between (b+2) and (b+1) is the size of 10 ints.
First, with int *b[5] you are not creating a two dimensional array, but an array of pointers.
The elements of the array b are pointers. Each occupies the size of a pointer, which depends on your architecture. In a 64-bits architecture it will probably occupy 64 bits (8 bytes). You can check that by printing sizeof(int*) or sizeof(b[0])
Memory allocation will look like
b
+-----+
| | +------+------+-----------+-----+-----+-----+-----+
| b[0]+--------------> | | | | | | | |
| | +------+------+-----------+-----+-----+-----+-----+
+-----+
| | +------+------+-----------+-----+-----+-----+-----+
| b[1]+--------------> | | |....... | | | | |
| | +------+------+-----------+-----+-----+-----+-----+
+-----+
| | +------+------+-----------+-----+-----+-----+-----+
| b[2]+--------------> | | | ...... | | | | |
| | +------+------+-----------+-----+-----+-----+-----+
+-----+
| | +------+------+-----------+-----+-----+-----+-----+
| b[3]+--------------> | | | ...... | | | | |
| | +------+------+-----------+-----+-----+-----+-----+
+-----+
| | +------+------+-----------+-----+-----+-----+-----+
| b[4]+--------------> | | | ...... | | | | |
| | +------+------+-----------+-----+-----+-----+-----+
+-----+
b will point to b[0], after decay, and b + 1 will give the address of b[1]. Size of pointer on your machine is 8 bytes, therefore you are getting a difference of 8 in the address.
Beside of this
Do not cast return value of malloc
b[loop]=malloc(10*sizeof(int));
and use %p for pointer data type
printf("b=%p \n",(void *)b);
printf("(b+1)=%p \n",(void *)(b+1));
printf("(b+2)=%p \n",(void *)(b+2));
What you've declared is not technically a two dimensional array but an array of pointers to int, each of which points to an array of int. The reason array[0] and array[1] are 8 bytes apart is because you have an array of pointers, and pointers on your system are 8 bytes.
When you allocate each individual 1 dimensional array, they don't necessarily exist next to each other in memory. If on the other hand you declared int b[5][10], you would have 10 * 5 = 50 contiguous integers arranged in 5 rows of 10.

Printing two 2D arrays side by side

I've just started doing a unit of programming in C and my first assignment is to make a simple console version of the classic Battleship game.
A part of this - and the part I'm having trouble with at the moment - is displaying information to the player at each turn.
This is what we've been asked to have our display look like:
And, with a minimum of fuss, I've got mine looking like this:
(My Player grid is empty at the moment because its 2D array is empty, but if I use an array with something in it, it's fine.)
My header file:
/* Header files. */
#include <stdio.h>
#include <stdlib.h>
#define UNKNOWN ' '
#define SIZE 10
/* Function prototypes. */
void init(char playerHidden[SIZE][SIZE], char playerReveal[SIZE][SIZE],
char computHidden[SIZE][SIZE], char computReveal[SIZE][SIZE]);
void displayKnownInfo(char playerReveal[SIZE][SIZE],
char playerHidden[SIZE][SIZE],
char computReveal[SIZE][SIZE]);
My C source file:
#include "bship.h"
int main(void)
{
/* Stores player ship position information secret to opponent. */
char playerHidden[SIZE][SIZE];
/* Stores player ship position information known to opponent. */
char playerReveal[SIZE][SIZE];
/* Stores computer ship position information secret to opponent. */
char computHidden[SIZE][SIZE];
/* Stores computer ship position information known to opponent. */
char computReveal[SIZE][SIZE];
init(playerHidden, playerReveal,
computHidden, computReveal);
displayKnownInfo(playerReveal, playerHidden, computReveal);
return EXIT_SUCCESS;
}
/****************************************************************************
* Function init() initialises every cell in the four grids to a safe default
* value. The UNKNOWN constant is used for the initialisation value.
****************************************************************************/
void init(char playerHidden[SIZE][SIZE], char playerReveal[SIZE][SIZE],
char computHidden[SIZE][SIZE], char computReveal[SIZE][SIZE])
{
/*Variables i and j for each dimension of the Arrays*/
int x,y;
/*For each increment BETWEEN 0 and 'SIZE', firstly for i;*/
for(y=0; y<SIZE; y++)
{
/*And then for j;*/
for(x=0; x<SIZE; x++)
{
/*Populate that cell with the constant UNKNOWN*/
playerHidden[x][y]=UNKNOWN;
playerReveal[x][y]=UNKNOWN;
computHidden[x][y]=UNKNOWN;
computReveal[x][y]=UNKNOWN;
}
}
}
/****************************************************************************
* Function displayKnownInfo() presents revealed information about the game in
* the format below. In this example, both contestants have made five
* guesses.
* As you can see, the computer player got lucky with all five guesses and has
* sunk the human players' aircraft carrier. The identity of the ship was
* revealed when the aircraft carrier was HIT the fifth time.
* The human player has been less lucky. The first four guesses were a MISS.
* However, the fifth guess was a HIT on the computer players' submarine. The
* human player does not yet know the identity of this ship yet as it is still
* afloat.
* All other squares are still UNKNOWN.
*
* Player | Computer
* 1 2 3 4 5 6 7 8 9 0 | 1 2 3 4 5 6 7 8 9 0
* +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+
* a |A| | | | | | | | | | | a | | | | | | | | | | |
* +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+
* b |A| | | | | | | | | | | b | | | | | | | | | | |
* +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+
* c |A| | | | | | | | | | | c | | | | | | |=| | | |
* +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+
* d |A| | | | | | | | | | | d | | |x| | | | | | | |
* +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+
* e |A| | | | | | | | | | | e | | | | | | | | | | |
* +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+
* f | | | | | | | | | | | | f | | | | |=| | | | | |
* +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+
* g | | | | | | | | | | | | g | | | | | | | | | | |
* +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+
* h | | | | | | | | | | | | h | |=| | | | |=| | | |
* +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+
* i | | | | | | | | | | | | i | | | | | | | | | | |
* +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+
* j | | | | | | | | | | | | j | | | | | | | | | | |
* +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+
* Aircraft Carrier (5/5) | 0/5 ships sunk.
* Battleship (0/4) | 1 hits.
* Destroyer (0/3) | 4 misses.
* Frigate (0/3) |
* Submarine (0/2) |
****************************************************************************/
void displayKnownInfo(char playerReveal[SIZE][SIZE],
char playerHidden[SIZE][SIZE],
char computReveal[SIZE][SIZE])
{
/*Ints for stepping through the arrays*/
int i,j;
/*First row identifier*/
char row='a';
/*Printing first few lines.*/
printf(" Player | Computer\n");
printf(" 1 2 3 4 5 6 7 8 9 0 | 1 2 3 4 5 6 7 8 9 0\n");
printf(" +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+\n");
printf(" %c |", row);
/*Loop through the arrays*/
for(i=0; i<SIZE; i++)
{
for(j=0; j<SIZE; j++)
{
/*Print the char at [i][j] with a '|' afterwards.*/
printf("%c|",playerReveal[i][j]);
}
/*After reaching column '0' on the display, increment the row identifier*/
row++;
/*And print the 'spacer' row.*/
printf("\n +-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+");
/*If the current row identifier is less than 'k', we want to print it*/
if(row<'k')
{
printf("\n %c |",row);
}
else
{
printf("\n");
}
/*And continue until the array has been printed in full.*/
}
}
}
Eventually, the PlayerHidden array will be overlaid on the PlayerReveal array when a player's ship has been sunk and its identity 'revealed', but for now I'm just wanting to get the computer half of the display working.
Just add this to your code after the second loop where you prints stuff:
printf(" %c |", row);
for(j=0; j<SIZE; j++)
{
/*Print the char at [i][j] with a '|' afterwards.*/
printf("%c|",computReveal[i][j]);
}
So your code looks like:
//...
/*Loop through the arrays*/
for(i=0; i<SIZE; i++)
{
for(j=0; j<SIZE; j++)
{
/*Print the char at [i][j] with a '|' afterwards.*/
printf("%c|",playerReveal[i][j]);
}
printf(" %c |", row);
for(j=0; j<SIZE; j++)
{
/*Print the char at [i][j] with a '|' afterwards.*/
printf("%c|",computReveal[i][j]);
}
//...
Your problem is that you're only printing out the player portion. Take a look at the code:
for(i=0; i<SIZE; i++)
{
for(j=0; j<SIZE; j++)
{
/*Print the char at [i][j] with a '|' afterwards.*/
printf("%c|",playerReveal[i][j]);
}
// ...
}
You need to have another loop where you print out the computerReveal array
for(i=0; i<SIZE; i++)
{
for(j=0; j<SIZE; j++)
{
/*Print the char at [i][j] with a '|' afterwards.*/
printf("%c|",playerReveal[i][j]);
}
for(j=0; j<SIZE; j++)
{
/*Print the char at [i][j] with a '|' afterwards.*/
printf("%c|",computReveal[i][j]);
}
// ...
}
That should do it. You're printing out the full width row separators, but not the portion of the array that creates the cell separators

Multidimensional arrays allocated through calloc

I have a question about how memory is allocated when I calloc. I had a look at this question, but it doesn't address how memory is allocated in the case of a dynamically allocated two dimensional array.
I was wondering if there was a difference in the memory representation between the following three ways of dynamically allocating a 2D array.
Type 1:
double **array1;
int ii;
array1 = calloc(10, sizeof(double *));
for(ii = 0; ii < 10; ii++) {
array1[ii] = calloc(10, sizeof(double));
}
// Then access array elements like array1[ii][jj]
Type 2:
double **array1;
int ii;
array1 = calloc(10 * 10, sizeof(double *));
// Then access array elements like array1[ii + 10*jj]
Type 3:
double **array1;
int ii;
array1 = malloc(10 * 10, sizeof(double *));
// Then access array elements like array1[ii + 10*jj]
From what I understand of calloc and malloc, the difference between the last two is that calloc will zero all the elements of the array, whereas malloc will not. But are the first two ways of defining the array equivalent in memory?
Are the first two ways of defining the array equivalent in memory?
Not quite. In the second type they are almost certainly contiguous, while in the first type this is not sure.
Type 1: in-memory representation will look like this:
+---+---+---+---+---+---+---+---+---+---+
double| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+---+---+
^
|------------------------------------
. . . . . . . . | // ten rows of doubles
-
+---+---+---+---+---+---+---+---+---+--|+
double| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0||
+---+---+---+---+---+---+---+---+---+--|+
^ . . . -
| ^ ^ ^ . . . . . |
| | | | ^ ^ ^ ^ ^ |
+-|-+-|-+-|-+-|-+-|-+-|-+-|-+-|-+-|-+-|-+
array1[ii]| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | // each cell points to ten doubles
+---+---+---+---+---+---+---+---+---+---+
^
|
|
+-|-+
array1| | |
+---+
Type 2: in-memory representation will look like this:
+---+---+---+---+---+---+---+---+---+---+ +---+
double| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 |
+---+---+---+---+---+---+---+---+---+---+ +---+
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | | | | |
| | | | | | | | | | |
+-|-+-|-+-|-+-|-+-|-+-|-+-|-+-|-+-|-+-|-+ +-|-+
array1[ii]| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... |99 | // each cell points to one double
+---+---+---+---+---+---+---+---+---+---+ +---+
^
|
|
+-|-+
array1| | |
+---+
Simple Example
#include<stdio.h>
#include<stdlib.h>
int **d ;
int sum();
//----------------------------------------------
int main(){
d = (int **)calloc(3,sizeof(int*));
printf("\n%d",sum());
}
//-----------------------------------------------
int sum(){
int s = 0;
for(int i = 0; i < 3; i++)
d[i] = (int *) calloc (3,sizeof(int));
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
d[i][j] = i+j;
s += d[i][j];
printf("\n array[%d][%d]-> %d",i,j,d[i][j]);
}
}
return s;
}
In the first way, you allocate 10 pointers to double, and 100 double. In the second way you allocate 100 pointers to double.The other difference is that in the second way, you allocate one big block of memory, so that all the elements of your array are in the same block. In the first way, each "row" of your array is in a different block than the others.
Though, in the second way, your array should be a double* instead of a double**, because in this way of allocating, your array only contains pointers to double, not double.
On the case 1, you make:
array1[0] -> [memory area of 10]
array1[1] -> [memory area of 10] ...
array1[N] -> [memory area of 10] ...
Note: You cannot assume that the memory area is continuous, there might be gaps.
On the case 2 you make:
array1 -> [memory area of 100]
The case 3 is same as the case 2, but its not initializing the memory. Difference between case 1 and 2 & 3 is that on the first case you really have 2D memory structure. For example if you want to swap rows 1 and 2, you could just swap the pointers:
help = array1[1]
array1[1] = array1[2]
array1[2] = help
But if you want to do the same in the 2&3 case you need to do real memcpy. What to use? Depends what you are doing.
The first way uses bit more memory: if you would have array of 1000x10 then the first version will use 1000*8 + 1000*10*8 (on 64bit system), while the 2&3 will only use 1000*10*8.

Resources