However, every time I reference own[i][j], I get an error saying that the subscripted value is neither array nor pointer nor vector.
That's right. own[i] is equivalent to *(own + i), which has type int. You cannot apply the subscript operator to an int.
Note that what your code appears to be trying to create is not a two-dimensional array, but rather an array of pointers. If that's really what you want then own should have type int **, and you should adjust the first calloc() call accordingly. If you really want dynamic allocation of a 2D array, though, then that would be:
int (*own)[3];
own = calloc(mem_size, sizeof(*own));
Note that there is no need then to allocate (or free) the rows separately.
Note also, however, that if you do not ever need to reallocate own before it goes out of scope, if you can assume at least a C99 compiler, and if mem_size is will never be too large then you can do this even more easily via a variable-length array:
int own[mem_size][3] = {{0}};
No explicit dynamic allocation or deallocation is needed at all in that case, and the initializer can be omitted if unneeded. (I include the initializer because calloc() performs equivalent initialization of the allocated space.) "Too large" should be interpreted in relation to the array being allocated on the stack.
However, every time I reference own[i][j], I get an error saying that the subscripted value is neither array nor pointer nor vector.
That's right. own[i] is equivalent to *(own + i), which has type int. You cannot apply the subscript operator to an int.
Note that what your code appears to be trying to create is not a two-dimensional array, but rather an array of pointers. If that's really what you want then own should have type int **, and you should adjust the first calloc() call accordingly. If you really want dynamic allocation of a 2D array, though, then that would be:
int (*own)[3];
own = calloc(mem_size, sizeof(*own));
Note that there is no need then to allocate (or free) the rows separately.
Note also, however, that if you do not ever need to reallocate own before it goes out of scope, if you can assume at least a C99 compiler, and if mem_size is will never be too large then you can do this even more easily via a variable-length array:
int own[mem_size][3] = {{0}};
No explicit dynamic allocation or deallocation is needed at all in that case, and the initializer can be omitted if unneeded. (I include the initializer because calloc() performs equivalent initialization of the allocated space.) "Too large" should be interpreted in relation to the array being allocated on the stack.
Use:
int ** own; // int**, not int*
own = calloc(mem_size, sizeof(int*)); //int*, not int
// And remove the explicit cast.
c - Multidimensional arrays allocated through calloc - Stack Overflow
malloc() question for 2d array
c - How to calloc a 2D array without valgrind errors? - Stack Overflow
c++ - 2d array, using calloc in C - Stack Overflow
Videos
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;
}
I am confused as to how and what malloc() is exactly doing/making with my specific line.
I am trying to allocate for a game board.
I have the lines:
char *board;
int length = 7;
int height = 6;
board = (char*)malloc(length * height * sizeof(char));
printf("%lu\n", sizeof(board)); //to test the size of my boardThe board results as having a size of 8, which confuses me because I am intending it to have a size of 42 (7 * 6 = 42). I think I remember reading somewhere that for 2d arrays in C, the coordinates of an index are interpreted as if it were a 1d array. So a row of 7, col of 6 would just go to a size of 42 (or something of the sort? I feel I have something wrong about this).
For comparison, the code:
char board[7][6]
printf("%lu", sizeof(board));gives me a resulting board size of 42 as expected.
So can anyone explain to me what it is I am doing wrong with malloc? What is the difference between the two ways I am creating a 2d array board, one being through malloc, the other through the statement char board[7][6]; ?
You're not allocating the proper amount of size for the first allocation:
wagner =(int **)calloc((sizeofvstup1+1),sizeof(int));
Here you're allocating space for an array of pointers, but you're passing sizeof(int) for the element size. If an int is smaller than an int *, then you don't have enough space and you end up reading/writing past the end of the array.
Change the element size of the allocation to sizeof(int *). Also, don't cast the return value of calloc:
wagner = calloc((sizeofvstup1 + 1), sizeof(int *));
As others mentioned the code uses the wrong size for the 1st allocation.
To never having to think again which size to use when allocating there is simple trick:
Given that the result of a memory allocation is always assigned to a pointer just simply request to allocate (multiples of) the size this target pointer is pointing to by doing:
int **wagner;
wagner = calloc(sizeofvstup1 + 1, sizeof *wagner);
for (size_t = 0; i < (sizeofvstup1 + 1); ++i) {
wagner[i] = calloc(sizeofvstup2 + 1, sizeof *wagner[i]);
}
(all other changes to the code are unrelated to this "trick")
This way the code would even survive a change from
int ** wagner;
to let's say
double ** wagner;
without any modifications.
No the code is not in a function.
You can't just put arbitrary statements outside of functions in C and C++. What you can do though is use a function to initialize the variable:
char** init_lines() {
char** ln = /* ... */;
// your allocations etc. here
return ln;
}
char** lines = init_lines();
You tagged the question with C++ -- why not use a std::vector<std::vector<char> > for this?
Looking at the compiler error, it looks like you're missing a semicolon before one of your for loops -- the code you posted seems to work perfectly fine here.
This
int ** numberOfConstPiArray = calloc(invariannumberOfUniqueKernels * kernelColumnCount, sizeof(int *));
is not an allocation of a two-dimensional array because at least the type of numberOfConstPiArray is int ** instead of for example int ( * )[kernelColumnCount].
If your compiler supports variable length arrays then you could use the following approach as it is shown in the demonstrative program
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
size_t n = 5;
int ( *a )[n] = calloc( n * n, sizeof( int ) );
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ ) a[i][j] = i * n + j;
}
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ ) printf( "%2d ", a[i][j] );
putchar( '\n' );
}
free( a );
return 0;
}
The program output is
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
Or you can allocate an array of arrays the following way.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
size_t n = 5;
int **a = calloc( n, sizeof( int * ) );
for ( size_t i = 0; i < n; i++ )
{
a[i] = calloc( n, sizeof( int ) );
}
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ ) a[i][j] = i * n + j;
}
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < n; j++ ) printf( "%2d ", a[i][j] );
putchar( '\n' );
}
for ( size_t i = 0; i < n; i++ )
{
free( a[i] );
}
free( a );
return 0;
}
The program output is the same as shown above.
numberOfConstPiArray[countKernel][col]
is getting an int* from numberOfConstPiArray[countKernel], then trying to dereference col'th element of this int*, and fails, as numberOfConstPiArray[countKernel] was not initialized with an reference to int array memory.
You may use instead:
int * numberOfConstPiArray = calloc(invariannumberOfUniqueKernels * kernelColumnCount, sizeof(int));
memset(numberOfConstPiArray, 0, invariannumberOfUniqueKernels * kernelColumnCount, sizeof(int));
...
numberOfConstPiArray[countKernel * kernelColumnCount + col] = 1;
So I'm reading the code from the filter problem and having a hard time visualizing this line.
According to the documentation for calloc, it's *calloc(n, element-size);
So the left side is basically saying "create a pointer called image, that points to an array of length [width], and the element in the array is of type RBGTRIPLE. This is a single 1D array with length [width].
On the right-hand side, calloc is allocating enough memory for the entire image.
I struggle to see how a 1D array somehow turns into a 2D array?
does calloc() only gives the amount of memory, not define the structure of the memory?
why isn't the left side coded like this "RBGTRIPLE(*image)[height][width]" ?
it initiates an array of length[width], but then after the calloc, you can index the image as image[row][column]
// Allocate memory for image
RGBTRIPLE(*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));