Reputation: 61
3D version of this array allocation seems to work fine, but adding a fourth dimension apparently causes a segfault. Edit: (Turns out the pointer stuff was fine, just a pair of typos in the inner loop)
#include <stdio.h>
#include <stdlib.h>
#define M 2
#define N 3
#define O 4
#define P 5
int main()
{
int ****A = malloc(sizeof(int***)*M);
int i, j, k, m;
if(!A)
{
printf (" **** Out of Memory");
}
for(i = 0; i < M; i++)
{
A[i] = malloc(sizeof(int**)*N);
if(!A[i])
{
printf(" *** Out of Memory");
}
for(j = 0; j < N; j++)
{
A[i][j] = malloc(sizeof(int*)*O);
if(!A[i][j])
{
printf(" ** Out of Memory");
}
for(k = 0; k < O; k++)
{
/* TYPO 1 - former site of main problem, a "==" typo */
A[i][j][k] = malloc(sizeof(int)*P);
if(!A[i][j][k])
{
printf(" * Out of Memory\n");
}
/* TYPO 2 - former site of ")A;" typo unrelated to main problem */
printf("Allocation: A[i][j][k] at %p, A[i][j]: %p, A[i]: %p, A: %p\n", A[i][j][k], A[i][j], A[i], A);
}
}
}
return 0;
}
Mingw gives an out of memory
error after 18 – 26 allocations, no matter what size goes in M, N, O, P.
Same code running on linux gcc produces errors and a segfault immediately
3-dimensional version of this code (just one less for-loop) works and doesn’t produce errors.
mingw output:
Allocation: A[i][j][k] at 00B326F8, A[i][j]: 00B30D60, A[i]: 00B30D48, A: 76FD74CD
Allocation: A[i][j][k] at 00B300C0, A[i][j]: 00B30D60, A[i]: 00B30D48, A: 76FD74CD
Allocation: A[i][j][k] at 69575C3A, A[i][j]: 00B30D60, A[i]: 00B30D48, A: 76FD74CD
Allocation: A[i][j][k] at 776F646E, A[i][j]: 00B30D60, A[i]: 00B30D48, A: 76FD74CD
Allocation: A[i][j][k] at 00B33700, A[i][j]: 00B30DF8, A[i]: 00B30D48, A: 76FD74CD
Allocation: A[i][j][k] at 00B300C0, A[i][j]: 00B30DF8, A[i]: 00B30D48, A: 76FD74CD
Allocation: A[i][j][k] at 45434F52, A[i][j]: 00B30DF8, A[i]: 00B30D48, A: 76FD74CD
Allocation: A[i][j][k] at 524F5353, A[i][j]: 00B30DF8, A[i]: 00B30D48, A: 76FD74CD
Allocation: A[i][j][k] at 00B33700, A[i][j]: 00B30E90, A[i]: 00B30D48, A: 76FD74CD
Allocation: A[i][j][k] at 00B300C0, A[i][j]: 00B30E90, A[i]: 00B30D48, A: 76FD74CD
Allocation: A[i][j][k] at 6F646E69, A[i][j]: 00B30E90, A[i]: 00B30D48, A: 76FD74CD
Allocation: A[i][j][k] at 535C7377, A[i][j]: 00B30E90, A[i]: 00B30D48, A: 76FD74CD
Allocation: A[i][j][k] at 00B33700, A[i][j]: 00B30F40, A[i]: 00B30F28, A: 76FD74CD
Allocation: A[i][j][k] at 00B300C0, A[i][j]: 00B30F40, A[i]: 00B30F28, A: 76FD74CD
Allocation: A[i][j][k] at 6D766E44, A[i][j]: 00B30F40, A[i]: 00B30F28, A: 76FD74CD
Allocation: A[i][j][k] at 5C3A433B, A[i][j]: 00B30F40, A[i]: 00B30F28, A: 76FD74CD
Allocation: A[i][j][k] at 00B30FD8, A[i][j]: 00B304A0, A[i]: 00B30F28, A: 76FD74CD
Allocation: A[i][j][k] at 00B300C0, A[i][j]: 00B304A0, A[i]: 00B30F28, A: 76FD74CD
Allocation: A[i][j][k] at 00000231, A[i][j]: 00B304A0, A[i]: 00B30F28, A: 76FD74CD
* Out of Memory
Allocation: A[i][j][k] at 00000000, A[i][j]: 00B304A0, A[i]: 00B30F28, A: 76FD74CD
Allocation: A[i][j][k] at 00B304D8, A[i][j]: 00B313E0, A[i]: 00B30F28, A:
76FD74CD
Allocation: A[i][j][k] at 00B300C0, A[i][j]: 00B313E0, A[i]: 00B30F28, A: 76FD74CD
Allocation: A[i][j][k] at 6F646E69, A[i][j]: 00B313E0, A[i]: 00B30F28, A: 76FD74CD
Allocation: A[i][j][k] at 00007377, A[i][j]: 00B313E0, A[i]: 00B30F28, A: 76FD74CD
Process returned 255 (0xFF) execution time : 3.891 s
On linux, identical code produces:
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617028, A[i]: 0x9617018, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617028, A[i]: 0x9617018, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617028, A[i]: 0x9617018, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617028, A[i]: 0x9617018, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x96170a0, A[i]: 0x9617018, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x96170a0, A[i]: 0x9617018, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x96170a0, A[i]: 0x9617018, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x96170a0, A[i]: 0x9617018, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617118, A[i]: 0x9617018, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617118, A[i]: 0x9617018, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617118, A[i]: 0x9617018, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617118, A[i]: 0x9617018, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x96171a0, A[i]: 0x9617190, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x96171a0, A[i]: 0x9617190, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x96171a0, A[i]: 0x9617190, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x96171a0, A[i]: 0x9617190, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617218, A[i]: 0x9617190, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617218, A[i]: 0x9617190, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617218, A[i]: 0x9617190, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617218, A[i]: 0x9617190, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617290, A[i]: 0x9617190, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617290, A[i]: 0x9617190, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617290, A[i]: 0x9617190, A: 0x24ab80
* Out of Memory
Allocation: A[i][j][k] at (nil), A[i][j]: 0x9617290, A[i]: 0x9617190, A: 0x24ab80
Segmentation fault
Edit: It wasn't a pointer notation problem at all. Had a random "==" instead of "=" and a misplaced ")" in the print statement.
Upvotes: 0
Views: 683
Reputation: 30926
A[i][j][k] == (int*)malloc(sizeof(int)*P);
And then you try to access it
if(!A[i][j][k])
Giving you segmentation fault.
This worked for 3
dimension? Nope. Maybe because you didn't have this loop then.
Correction will be
A[i][j][k] = malloc(sizeof(int)*P);
You don't need that casting - it's redundant.
Also all these 4 mallocs can be much cleaner and hasslefree if you do this
int ****A = malloc(sizeof *A * M);
and
A[i] = malloc(sizeof *A[i] * N);
Also compile your code like this
gcc -Wall -Werror progname.c
This will throw an warning making you aware of this equality - equal problem.
Illustration code:-
#include <stdio.h>
#include <stdlib.h>
#define M 2
#define N 3
#define O 4
#define P 5
int main(void)
{
int ****A = malloc(sizeof*A*M);
if(!A)
{
perror(" *** Out of Memory");
exit(EXIT_FAILURE);
}
for(size_t i = 0; i < M; i++)
{
A[i] = malloc(sizeof *A[i]*N);
if(!A[i])
{
perror(" *** Out of Memory");
exit(EXIT_FAILURE);
}
for(size_t j = 0; j < N; j++)
{
A[i][j] = malloc(sizeof(int*)*O);
if(!A[i][j])
{
perror(" *** Out of Memory");
exit(EXIT_FAILURE);
}
for(size_t k = 0; k < O; k++)
{
A[i][j][k] = malloc(sizeof *A[i][j][k]*P);
if(!A[i][j][k])
{
perror(" *** Out of Memory");
exit(EXIT_FAILURE);
}
printf("Allocation: A[i][j][k] at %p, A[i][j]: %p, A[i]: %p, A: %p\n", (void*)A[i][j][k], (void*)A[i][j], (void*)A[i], (void*)A);
}
}
}
return 0;
}
Upvotes: 5