Can't pass multidimensional array to structure - c

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
+---+---+---+---+

Related

How to realloc 2d struct pointer with different size

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);

if the maximum capacity of character is 256 how to store character array of 1000?

If the maximum capacity of character is 256 how to store character array of 1000?
is it possible to declare:
char s[1000];
Yes, it is certainly possible.
char s[1000];
You can think of 1000 as the "length" of the array and 256 as the "width". You get an array of 1000 chars. Each char is 8 bits (on the machine you're using, at least), and can therefore store 256 distinct values. (And, actually, it would probably be more appropriate to think of the "width" as being 8, not 256.)
Here is your array, with each box representing one char:
+---+---+---+---+---+---+---+---+- -+---+
s: | | | | | | | | | ... | |
+---+---+---+---+---+---+---+---+- -+---+
0 1 2 3 4 5 6 7 999
Or here it is showing the individual bits:
+---+---+---+---+---+---+---+---+- -+---+
s: | | | | | | | | | | | 7
+---+---+---+---+---+---+---+---+- -+---+
| | | | | | | | | | | 6
+---+---+---+---+---+---+---+---+- -+---+
| | | | | | | | | | | 5
+---+---+---+---+---+---+---+---+- -+---+
| | | | | | | | | | | 4
+---+---+---+---+---+---+---+---+- -+---+ bit
| | | | | | | | | ... | | 3 number
+---+---+---+---+---+---+---+---+- -+---+
| | | | | | | | | | | 2
+---+---+---+---+---+---+---+---+- -+---+
| | | | | | | | | | | 1
+---+---+---+---+---+---+---+---+- -+---+
| | | | | | | | | | | 0
+---+---+---+---+---+---+---+---+- -+---+
0 1 2 3 4 5 6 7 999
array index
Suppose we put a string in the array, either by calling strcpy:
strcpy(s, "Hello!");
or my initializing it when we declare it:
char s[1000] = "Hello!";
By bytes it looks like this:
+---+---+---+---+---+---+---+---+- -+---+
s: | H | e | l | l | o | ! |\0 | | ... | |
+---+---+---+---+---+---+---+---+- -+---+
0 1 2 3 4 5 6 7 999
Or by bits it looks like this:
+---+---+---+---+---+---+---+---+- -+---+
s: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | | 7
+---+---+---+---+---+---+---+---+- -+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 0 | | | | 6
+---+---+---+---+---+---+---+---+- -+---+
| 0 | 1 | 1 | 1 | 1 | 1 | 0 | | | | 5
+---+---+---+---+---+---+---+---+- -+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | | 4
+---+---+---+---+---+---+---+---+- -+---+ bit
| 1 | 0 | 1 | 1 | 1 | 0 | 0 | | ... | | 3 number
+---+---+---+---+---+---+---+---+- -+---+
| 0 | 1 | 1 | 1 | 1 | 0 | 0 | | | | 2
+---+---+---+---+---+---+---+---+- -+---+
| 0 | 0 | 0 | 0 | 1 | 0 | 0 | | | | 1
+---+---+---+---+---+---+---+---+- -+---+
| 0 | 1 | 0 | 0 | 1 | 1 | 0 | | | | 0
+---+---+---+---+---+---+---+---+- -+---+
0 1 2 3 4 5 6 7 999
array index
And there are 993 spaces in the array left over.
[P.S. to nitpickers: Yes, those are ASCII codes, and no, character encoding is not specified by the C Standard. But I think we can safely assume that those are the codes the questioner would see.]
The 256 is the number of values in a single char (which is often an 8 bits byte, and 256 = 28).
(caveat, the C11 standard allows wider char-s, e.g. of 32 bits; but this is very uncommon)
A string is an array or a memory zone containing several char-s, and conventionally terminated by a zero byte.
You can have very big strings, notably using C dynamic memory allocation. For instance, on some computers
char*hugestring = malloc(1000000000);
can succeed. Then you could fill that billion-bytes string. On many computers, that malloc call would fail, and you always need to check the result of malloc, at least by following the above line with
if (!hugestring) { perror("malloc hugestring"); exit(EXIT_FAILURE); };
If you use malloc, don't forget to later call free (you need to have conventions about who is responsible for that); otherwise you have a memory leak. BTW the asprintf, strdup and open_memstream functions are very useful (but not available everywhere) to conveniently build dynamically allocated strings (internally malloc is used by them). Tools like valgrind are helpful to help detecting memory leaks.
You can also have arrays. If they are local variables (a.k.a. automatic variables) they generally sit in the call stack (unless the compiler optimized for them).
For example, using snprintf to safely fill a local buffer (without buffer overflow),
char buffer[100];
snprintf(buffer, sizeof(buffer), "x=%d, name=%s", x, name);
but it is unreasonable to have large call frames, so a local array should generally be less than a few hundred bytes (or perhaps a few thousands of them). The entire call stack is generally limited to one or a few megabytes. Details are system specific.
Be aware of character encoding issues. In 2017 read at least utf8everywhere.org and about Unicode.... so think of char as a byte (since some UTF-8 characters need several bytes, so take several char-s to be represented, hence on my Linux desktop strlen("être") is 5 and sizeof("être") is 6 since the accentuated ê letter is UTF-8 encoded in two bytes). You might use some library like libunistring.
Look also into some C reference.
You seem to misinterpret what you refer to as "capacity" of a char. char is an 8-bit value, which means it can range anywhere from 0000 0000b () to 1111 1111b (255).
This only refers to one individual value. This means you can write char c = 20;, but not char c = 1000;.
As such, this means that there are 256 different possible values for a single char.
Arrays are a different concept: An array stores multiple values of one specific type - such as an array of characters.
To answer you question: Yes, you can store 1000 char values in an array, like char s[1000] as Steve Summit suggested.
Naturally, if you have 1000 chars, this will mean there will be duplicates (since there are only 256 unique characters possible).

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.

Initialisation of Character Arrays [duplicate]

This question already has answers here:
No compiler error when fixed size char array is initialized without enough room for null terminator
(2 answers)
Closed 6 years ago.
If we declare an array of characters in C
Ex:
char label[] = "Hello";
We will have an array in memory which looks like this
--------------------------
| H | e | l | l | o | \0 |
--------------------------
where the extra null byte is added at the end of the array.
Scenario 1:
char label[10] = "Hello";
------------------------------------------
| H | e | l | l | o | \0 | | | | |
------------------------------------------
where it will have an extra 4 unused locations.
Scenario 2:
Here if we have exactly a string with 10 characters, will the \0 (null byte) still be added, which makes the char array to hold 11 characters?
char label[10] = "0123456789";
-----------------------------------------
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
-----------------------------------------
OR
----------------------------------------------
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | \0 |
----------------------------------------------
Your understanding is almost correct:
char label[10] = "Hello";
will initialize a 10 byte char array with | H | e | l | l | o |\0|\0|\0|\0|\0|.
Whereas for the last case:
char label[10] = "0123456789";
the array is also 10 char long, initialized with | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |. This array is therefore not null terminated and should not be used as a C string.

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