I used the codes below to create dynamic memory.
unsigned int *mem ;
mem = (unsigned int*) malloc(mallocSize);
However, I prefer to create an array of pointers.
Each pointers will link to one of the memory block.
but I prefer to create an array of pointers each pointer links to one of the memory block above
unsigned int **mem = (unsigned int **)malloc(sizeof(unsigned int *) * number_of_pointers);
// memset(mem, NULL, sizeof(unsigned int *) * number_of_pointers); // recommend it but not needed here, we always set NULL for safety.
for (int index = 0; index < number_of_pointers; index++)
mem[index] = (unsigned int *)malloc(sizeof(unsigned int) * number_of_ints);
to access individual elements mem[row_index][column_index]
to de-allocate, to reduce or remove memory leaks.
for (int index = 0; index < number_of_pointers; index++)
free(mem[index]);
free(mem);
rule of thumb, for me anyway, free should be call as often as malloc
I guess the below code should do it for you. You can create an array of pointers and then store the pointer to each of the memory block in each element of the array. But, the important point is that if you are having an array of unsigned int *, the size passed to malloc must be sizeof(unsigned int). You can modify the below example for other types.
unsigned int *mem[100];
for (i=0; i<100; i++)
{
mem[i] = malloc(sizeof(unsigned int));
}
Arrays have always compile-time fixed size in C. If that's okay with you, use array syntax:
unsigned int *mem[NUM_PTRS];
for (int i=0; i<NUM_PTRS; i++) {
mem[i] = malloc(mallocSize);
}
If you need to decide the size at runtime, you need a pointer-to-pointer:
unsigned int **mem;
mem = malloc(sizeof(unsigned int *) * num_ptrs);
for (int i=0; i<num_ptrs; i++) {
mem[i] = malloc(mallocSize);
}
unsigned int **pMemory;
pMemory = (int**)malloc(sizeof(unsigned int *) *number_of_pointers);
for(int index_to_pointer = 0; \
index_to_pointer < number_of_pointers; \
index_to_pointer++)
{ pMemory[index_to_pointer] = (int*)malloc(sizeof(unsigned int));}
I think this is how we allocated dynamic double dimension memory allocation. hope this will help the purpose.
Related
I have a struct[4] with inside a pointer.
I have to malloc this pointer for all the 4 structs
//Here a simplification of my code that produces the same error:
typedef struct{
int *val;
}test_T;
void testAllocSingle(test_T *in){
in->val = (int *)calloc(10, sizeof(int));
}
void testAlloc(test_T *in){
int i = 0;
for (i=0; i<4; i++){
testAllocSingle(&(in[i]));
}
}
void main(void){
test_T a[4];
test_T b[4];
testAlloc(a);
testAlloc(b);
memcpy(b, a, 4*10*sizeof(int));
//FATAL RUN-TIME ERROR: Array argument too small (16 bytes). Argument must contain at least 160 bytes (160 elements).
}
My allocated array is not visible to main.
I'm doing something wrong in passing variables, can anyone tell me where?
Thanks
It's not clear what you're trying to copy, but 4 * 10 * sizeof(int) is not correct in any case. You haven't allocated any single contiguous block that size.
If you want to copy just the array of structs, which just copies the pointers to the array, it's:
memcpy(b, a, 4 * sizeof(test_t));
Note that this causes a memory leak, because you never freed the memory that was allocated in b.
If you want to copy each of the arrays of ints, it's
for (int i = 0; i < 4; i++) {
memcpy(b[i].val, a[i].val, 10 * sizeof(int));
}
This doesn't leak anything, because it's just copying the integers in the arrays, not changing the pointers.
You're calculating size of a and b incorrectly. a and b are 4-elements array of test_T, each of test_T has a pointer to int array. a and b are not contiguous memory with size 4 * 10 * sizeof(int).
You might need instead:
memcpy(b, a, sizeof(a));
Another easiest way is copy with for() instead of memcpy to avoid confusion,
for(i=0;i<4;i++){
b[i] = a[i];
}
The data structures you have before memcpy() look like this in RAM:
Each of the rectangles is a continous block of memory. It can be in any place, not necessarily in a special order, and not in adjacent places.
When you do
b[i] = a[i];
then the storage pointed to by b[i] will be "leaked", that means you lose the reference to it and you can't free it. Both b[i] and a[i] will point to the same array of 10 ints.
When you do
memcpy(b, a, sizeof a);
then all storage pointed to by b[0] to b[3] will be leaked.
To copy all ints from a to b, you could use #Barmar's loop, or this one:
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 10; j++) {
b[i].val[j] = a[i].val[j];
}
}
thank you all for the answers.
Maybe I simplified this example too much.
Unfortunately, there are many other variables in the structure in question
An example closer to reality can be this:
#define MALLOC_SIZE (10) //in the original code is a variable
typedef struct{
int size;
int x;
double y;
char z[32];
int *val;
}test_T;
void setSize(test_T *in){
int i = 0;
for (i=0; i<4; i++){
in[i].size = 0;
in[i].size += sizeof(int);//size
in[i].size += sizeof(int);//x
in[i].size += sizeof(double);//y
in[i].size += (sizeof(char)*32);//z
in[i].size += (sizeof(int)*MALLOC_SIZE);
}
}
void testAllocSingle(test_T *in){
in->val = (int *)calloc(MALLOC_SIZE, sizeof(int));
}
void testAlloc(test_T *in){
int i = 0;
for (i=0; i<4; i++){
testAllocSingle(&(in[i]));
}
}
int main(void){
int tot_size = 0;
test_T a[4];
test_T b[4];
testAlloc(a);
testAlloc(b);
setSize(a);
tot_size = a[0].size + a[1].size + a[2].size + a[3].size;
memcpy(b, a, tot_size);
//FATAL RUN-TIME ERROR: Array argument too small (16 bytes). Argument must contain at least 160 bytes (160 elements).
return 0;
}
Copying everything "manually" remains possible but more inconvenient.
The strange thing is that I only have the problem if I compile and execute the code with NI CVI.
If I compile and execute the code with Eclipse+MinGW I haven't this error
I have a char * who points to the structure. Here is my structure:
struct prot
{
int size;
unsigned short codeAction;
void *data;
};
I recovered size and codeAction, but now I want to recover data.
And when I cast my last 8 bytes I have nothing in it.
The following code is just a test, it's a bad code:
char lol[4];
for (int i = 0; i < 4; i++)
lol[i] = test[i];
int size = *(int*)lol;
char loli[2];
int index = 0;
for (int i = 4; i < 6; i++)
{
loli[index] = test[i];
index++;
}
int code = *(short*)loli;
char lolo[8];
index = 0;
for (int i = 6; i < size; ++i)
{
lolo[index] = test[i];
index++;
}
void *newData = (char *)lolo; // how can I cast it?
How I can display the content of newData?
Your problem is that when casting lolo you actually cast a pointer to the char array you defined. So the result of the cast would be a char pointer to the first cell of the array.
Why don't you just use this as a struct and access the fields regularly?
Anyway, you want to use lolo as a 64 bit type pointer and the access what's in it.
void* newData = *((uint64_t*)lolo)
Besides, don't loop until size in the last for loop, loop only 8 times, until lolo is full. The number of bytes in newData itself (not what it points to) is constant, and is 4 bytes on 32bit machines, 8 bytes on 64bit ones.
Last thing - index++, not o++. o isn't defined, as much as I can see.
I don't understand why this works:
void main() {
int * b;
b = (int *)malloc(sizeof(int));
*b = 1;
printf("*b = %d\n", *b);
}
while this does not (gets segmentation fault for the malloc()):
void main() {
int ** a;
int i;
for (i = 0; i<= 3; i++) {
a[i] = (int*)malloc(sizeof(int));
*(a[i]) = i;
printf("*a[%d] = %d\n", i, *(a[i]));
}
}
since I find a[i] is just like b in the first example.
BTW, a[i] is equal to *(a+i), right?
You need to allocate memory for a first, so that you can access its members as a[i].
So if you want to allocate for 4 int * do
a = malloc(sizeof(int *) * 4);
for (i = 0; i<= 3; i++) {
...
}
or define it as array of integer pointers as
int *a[4];
a is a 2 dimensional pointer, you have to allocate both dimension.
b is a 1 dimensional pointer, you have to allocate only one dimension and that's what you're doing with
b = (int *)malloc(sizeof(int));
So in order the second example to work you have to allocate the space for the pointer of pointer
void main() {
int ** a;
int i;
a = (int**)malloc(4*sizeof(int*));
for (i = 0; i<= 3; i++) {
a[i] = (int*)malloc(sizeof(int));
*(a[i]) = i;
printf("*a[%d] = %d\n", i, *(a[i]));
}
The allocated pointer is written to uninitialized memory (you never set a to anything), causing undefined behavior.
So no, it's not at all equivalent to the code in the first example.
You would need something like:
int **a;
a = malloc(3 * sizeof *a);
first, to make sure a holds something valid, then you can use indexing and assign to a[0].
Further, this:
a[i] = (int*)malloc(sizeof(int));
doesn't make any sense. It's assigning to a[i], an object of type int *, but allocating space for sizeof (int).
Finally, don't cast the return value of malloc() in C.
actually malloc it's not that trivial if you really want safe and portable, on linux for example malloc could return a positive response for a given request even if the actual memory it's not even really reserved for your program or the memory it's not writable.
For what I know both of your examples can potentially return a seg-fault or simply crash.
#ruppells-vulture I would argue that malloc is really portable and "safe" for this reasons.
I have this C function:
fill_array(&data, &size);
void fill_array(int **data, int *size){
printf("Size is:");
scanf("%d", size);
*data = malloc(*size * sizeof(int *));
int i = 0;
for (i = 0; i < size; i++){
(*data)[i] = rand() % 11;
}
}
I want to assign data[i] for example, to random number. How to do such a thing? I have tried many variations, but all of the time my program crashes.
Thanks.
*data = malloc(*size * sizeof(**data));
(*data)[5] = 15;
Refer to cdecl web site.
Do not cast malloc
Edit according to the question edit
the for loop contains typo
for (i = 0; i < size; i++)
it should be
for (i = 0; i < *size; i++)
you can use (*data)[5] = 15; instead of this *data[5] = 15; Because precedence of [] greater than precedence of *..
As others said, you need to put parentheses to get the operator precedence right. If you want to use the "array" a lot, it might make sense to create a temporary variable that is easy to use:
int *p;
...
*data = malloc(*size * sizeof **data);
p = *data;
And then you could use p[5] etc.
Good program design dictates that we should keep memory allocation and the actual algorithm separated. To have a function that takes user input and allocates memory and performs some algorithm is probably not the optimal program design.
So the proper solution is not to patch that function to make it work, but instead to make some new ones:
int get_size_from_user (void)
{
int size;
printf("Size is:");
scanf("%d", &size);
return size;
}
bool alloc_array (int** array, int size)
{
*array = malloc(size * sizeof(int));
return *array != NULL;
}
void fill_array (int* array, int size)
{
// ...whatever you want to do here
data[5] = 15;
}
And look at that, the need for obscure syntax disappeared as soon as we improved the program design! Coincidence?
I have the following C code :
int *a;
size_t size = 2000*sizeof(int);
a = malloc(size);
which works fine. But if I have the following :
char **b = malloc(2000*sizeof *b);
where every element of b has different length.
How is it possible to do the same thing for b as i did for a; i.e. the following code would hold correct?
char *c;
size_t size = 2000*sizeof(char *);
c = malloc(size);
First, you need to allocate array of pointers like char **c = malloc( N * sizeof( char* )), then allocate each row with a separate call to malloc, probably in the loop:
/* N is the number of rows */
/* note: c is char** */
if (( c = malloc( N*sizeof( char* ))) == NULL )
{ /* error */ }
for ( i = 0; i < N; i++ )
{
/* x_i here is the size of given row, no need to
* multiply by sizeof( char ), it's always 1
*/
if (( c[i] = malloc( x_i )) == NULL )
{ /* error */ }
/* probably init the row here */
}
/* access matrix elements: c[i] give you a pointer
* to the row array, c[i][j] indexes an element
*/
c[i][j] = 'a';
If you know the total number of elements (e.g. N*M) you can do this in a single allocation.
The typical form for dynamically allocating an NxM array of type T is
T **a = malloc(sizeof *a * N);
if (a)
{
for (i = 0; i < N; i++)
{
a[i] = malloc(sizeof *a[i] * M);
}
}
If each element of the array has a different length, then replace M with the appropriate length for that element; for example
T **a = malloc(sizeof *a * N);
if (a)
{
for (i = 0; i < N; i++)
{
a[i] = malloc(sizeof *a[i] * length_for_this_element);
}
}
Equivalent memory allocation for char a[10][20] would be as follows.
char **a;
a=malloc(10*sizeof(char *));
for(i=0;i<10;i++)
a[i]=malloc(20*sizeof(char));
I hope this looks simple to understand.
The other approach would be to allocate one contiguous chunk of memory comprising header block for pointers to rows as well as body block to store actual data in rows. Then just mark up memory by assigning addresses of memory in body to the pointers in header on per-row basis. It would look like follows:
int** 2dAlloc(int rows, int* columns) {
int header = rows * sizeof(int*);
int body = 0;
for(int i=0; i<rows; body+=columnSizes[i++]) {
}
body*=sizeof(int);
int** rowptr = (int**)malloc(header + body);
int* buf = (int*)(rowptr + rows);
rowptr[0] = buf;
int k;
for(k = 1; k < rows; ++k) {
rowptr[k] = rowptr[k-1] + columns[k-1];
}
return rowptr;
}
int main() {
// specifying column amount on per-row basis
int columns[] = {1,2,3};
int rows = sizeof(columns)/sizeof(int);
int** matrix = 2dAlloc(rows, &columns);
// using allocated array
for(int i = 0; i<rows; ++i) {
for(int j = 0; j<columns[i]; ++j) {
cout<<matrix[i][j]<<", ";
}
cout<<endl;
}
// now it is time to get rid of allocated
// memory in only one call to "free"
free matrix;
}
The advantage of this approach is elegant freeing of memory and ability to use array-like notation to access elements of the resulting 2D array.
If every element in b has different lengths, then you need to do something like:
int totalLength = 0;
for_every_element_in_b {
totalLength += length_of_this_b_in_bytes;
}
return malloc(totalLength);
I think a 2 step approach is best, because c 2-d arrays are just and array of arrays. The first step is to allocate a single array, then loop through it allocating arrays for each column as you go. This article gives good detail.
2-D Array Dynamic Memory Allocation
int **a,i;
// for any number of rows & columns this will work
a = malloc(rows*sizeof(int *));
for(i=0;i<rows;i++)
*(a+i) = malloc(cols*sizeof(int));
malloc does not allocate on specific boundaries, so it must be assumed that it allocates on a byte boundary.
The returned pointer can then not be used if converted to any other type, since accessing that pointer will probably produce a memory access violation by the CPU, and the application will be immediately shut down.