EDIT: Thank you very much for your responses. I understand this properly now!
I am trying to learn more on C pointers. Tinkering around, I am questioning the difference between two actions I am using.
This code seems to work at first glance, but I am not sure of what's the difference, and if any of these two approaches is wrong in some way.
I'd like to know what's the difference between the two pieces of code, when I should I pass the adress, and when a pointer to an array?
Is any of the pieces wrong? If so, what would be the proper way?
having a simple struct grid pretty much like struct grid { int val; } (for demonstration purposes)
First piece of code. Passing address of the pointer to the array.
void set (mygrid *grid, int foo){
grid->bar = foo; //should this be '*grid->bar?' But this seems to work properly.
}
void main(){
int i;
int* array;
int max = 24;
array = malloc(sizeof(grid) * max);
for(i = 0; i < max; i++){
set(&array[i], 0);
}
}
Second piece of code. I am not entirely sure why this works, but the compiler doesn't output any warning.
I am supposed to be passing the pointer to the start of the array like this?
void set(mygrid *grid, int foo){
int i; int max = 24; //so this example code compiles :P
for(i = 0; i < max; i++){
grid[i].bar = foo;
}
}
void main(){
int* array;
int max = 24;
array = malloc(sizeof(grid) * max);
set(array, 0); //Why not &array?
}
Passing an array decays into a pointer that points to the first member of the array, just like &array[0].
In your second example, array is just a pointer, and the return value from malloc is just the address of the start of the block of memory you get.
It doesn't have to be used for an array; it could be used for storage of an arbitrary sizeof(int) * max bytes of data. An array (in C) is really just a nice way of thinking about & working with a solid block of memory divided up into equal size portions.
Secondly, you should understand how my_array[i] works. All it does is take the address of where your block of array data starts (which is the actual value of my_array), and then look at what value is stored at a particular offset from there. Specifically, if my_array is of a (made up) type of WhatEver, then it will access the data from my_array + i*sizeof(WhatEver) to my_array + (i+1)*sizeof(WhatEver).
On a related note (since you're learning C), it's highly recommended to check that the return from malloc is not NULL before doing anything with it.
I'm no C guru but am also trying to improve my understanding so if this is incorrect, please leave a comment or edit my answer so I can learn from my mistakes :)
In your first piece of code
grid->bar is same as (*grid).bar
. and using name of an array refers to its base address. so writing array is equivalent &array[0]
&array[i] is equivalent to array+i
array[i] is equivalent to *(array +i)
In you second piece of code i dont understand why there is no error because in your function set you do not declare max and i dont see a global max variable too.
also in your second piece of code you use
set(array,0) because array is already an integer pointer(see the declaration int * array).As far as i understand the mygrid is not a struct but is an array of structs in the second example
In C, an array is pretty much the same as a pointer. For me this isn't so amazing, since it is one of the earlier programming languages I learned, but if you're coming from a high level language where an array is a different type of object, then it might come across as strange.
Related
I'm new to C, and I was trying to write a function that would make permutations in array, given an array that has the new position of each elements.
An example of what I'd like to have :
int newPositions[] = {3,1,5,2,4};
int arr[] = {20,30,-1,9,1};
>> {-1,20,1,30,9}
I come from Java, so I had the basic functions we'd think of trying to do that, but I was surprised when I saw that I couldn't return an array in C, and I'm trying to find the best possible way of doing that without using too much memory. I thought about copying the array, but is there another solution?
Thanks
Here's how that could look:
#include <string.h>
void permutate(int** array, int* newPositions, int count)
{
int* arrayCopy = malloc(sizeof(int) * count);
memcpy(arrayCopy, array, sizeof(int) * count);
for (int i = 0; i < count; i++)
{
array[i] = arrayCopy[newPositions[i] - 1];
}
free(arrayCopy);
}
Be aware that arrays in C don't know their length (that's why count must be passed), so if there's a mismatch between both arrays and/or size, your program will do something unexpected or crash.
The are a lot of details to know about arrays and pointers in C. Please have a good look at this chapter of the famous C-FAQ.
I am trying to get a pointer to an array integers to be temporarily remapped in a function later on to save myself pointer math. I've tried to see if any other questions answered it, but I've been unable to reproduce the methods described here, here, and here.
Fundamentally, I just want to temporally treat an integer group and a 3D array to be sure that I don't mess up the pointer math. (I'm looking at this currently because the previous code had made inconsistent assignments to the memory).
#include <stdlib.h>
#define GROUPCOUNT 16
#define SENSORCOUNT 6
#define SENSORDIM 3
int main()
{
int *groupdata = (int *)calloc(GROUPCOUNT * SENSORCOUNT * SENSORDIM,sizeof(int));
int sensordata[SENSORCOUNT*SENSORDIM];
sensordata[7] = 42; //assign some data
int (*group3d)[GROUPCOUNT][SENSORCOUNT][SENSORDIM] = groupdata; //<---Here is the problem
group3d[1][5][1] = sensordata[7]; //I want to do this
free(groupdata);
}
In the example above, I want to handle groupdata as group3d temporarily for assignments, and I just cannot seem to wrap myself around the casting. I currently have macros that do the pointer math to enforce the correct structure, but if it was all just in the code, it would be even better when I pass it off. Any suggestions would be greatly appreciated.
note: The 3D cast is to be used in a function way in the bowels of the program. The example is just a minimally viable program for me to try to sort out the code.
When group3d is defined with int (*group3d)[GROUPCOUNT][SENSORCOUNT][SENSORDIM], then *group3d is a three-dimensional array. That would let you use it with (*group3d)[1][5][1].
To use it with group3d[1][5][1], you need group3d to be a pointer to a two-dimensional array:
int (*group3d)[SENSORCOUNT][SENSORDIM] = (int (*)[SENSORCOUNT][SENSORDIM]) groupdata;
(There are some technical concerns about C semantics in aliasing an array of int as an array of array of array of int, but this is not a problem in common compilers with default settings. However, it would be preferable to always use the memory as an array of array of array of int, not as an array of int.)
int l = 5, w = 10, h = 15;
int Data = 45;
int *k = malloc(l * w * h * sizeof *k);
// not use this k[a][b][c] = Data;
//use this is right
k[a*l*w + b*l + c] = Data;
In the example above, I want to handle groupdata as group3d
temporarily for assignments, and I just cannot seem to wrap myself
around the casting.
One possible solution is to create a multidimensional array dynamically like this. This way you won't have to cast things or worry about the dimensions.
int (*group3d)[GROUPCOUNT][SENSORCOUNT][SENSORDIM] = calloc(1, sizeof(int [GROUPCOUNT][SENSORCOUNT][SENSORDIM]));
(*group3d)[1][5][1] = sensordata[7]; //I want to do this
/* Then you can print it like */
printf("%d\r\n", (*group3d)[1][5][1]);
I came across an old code where I need to allocate memory for an array of matrices. Currently it is done by creating a structure matrix and allocating memory by making an arrray of structures.
Like so.
struct matrix
{
int x[13][13];
};
int main()
{
matrix *push = (matrix*)malloc(sizeof(matrix) * 1000);
//do stuff
free(push);
return 0;
}
But now the question.. Do I really need to do this? I know I am allowed to declare a variable of type int *matrix[13][13];
But I cant seem to figure out a way to allocate memory to this variable.
I tried matrix = (int***)malloc(sizeof(int[13][13])*1000); which results in
E0137 expression must be a modifiable lvalue and honestly in doesnt seem correct either
I know there are many better and creative ways of allocating an array like this, but I am curious
Questions
int *matrix[13][13] what will this kind of variable even mean or represent? Is it a pointer to a 2D matrix or s it an pointer to an array of 2D matrices?
How will I use the above mentioned variable?
How will I allocate memory for the above variable without using any more variables?
Clarifications
From comments it seems int *matrix[13][13] represents a matrix of 13x13 int*
What I am asking is actually, is there a way to have a variable with a dynamically allocated first dimension and static 2nd and 3rd dimensions without using structures typedefs etc
EDIT
As pointed out by felix
what I am looking for is int (*matrix)[13][13] = (int(*)[13][13])malloc(1000*sizeof(matrix));
I have noticed that sometimes beginner programmers are finding typedef-ing the multidimensional matrices which have to be dynamically allocated easier as it reduces the problem to the single star pointer and the sizeof of the defined type and pointer to it is much easier to understand.
#include <stdio.h>
typedef int my13x13matrix[13][13];
int main(void) {
my13x13matrix *mylargematrix = malloc(1000 * sizeof(*mylargematrix));
mylargematrix[999][12][12] = 5;
printf("%d \n", mylargematrix[999][12][12]);
return 0;
}
you can also use the single star pointer arithmetic.
my13x13matrix *anotherpointer = &mylargematrix[10];
(*anotherpointer)[5][5] = 1;
anotherpointer++;
(*anotherpointer)[5][5] = 2;
printf("%d %d\n", mylargematrix[10][5][5], mylargematrix[11][5][5]);
No, you don't want to use
int *matrix[13][13];
That will declare a [13][13] array of int*s.
You need
// pointer to "an array of 13 x 13 ints"
int (*matrix)[13][13];
or simplify it by using a type alias.
typedef int matrix_type[13][13];
matrix_type* matrix_ptr;
You can allocate memory for such a variable using
matrix_type* matrix_ptr = malloc(1000*sizeof(*matrix_ptr));
and assign values to it using
matrix_ptr[0][0][0] = 0;
...
matrix_ptr[999][12][12] = 0;
I'm new to programing and was given a task of making a function that puts one array into the other with the following criteria: a variable in the destination array will repeat only once and the source and destination array will be of the same size.
the function i came up with is:
int RemoveDup (int src[],int dst[])
//recive two array compare them and copy the src array to dst,and only the none reacuring
//numbers,the arrays must be from the same size
{
int size_src;
int size_dst;
int i,n=0;
size_src = sizeof(src)/sizeof(int);//determine the size of source array
size_dst = sizeof(dst)/sizeof(int);//determine the size of destination array
if (size_src = size_dst);//checks that the array are in the same size
{
for(i = 0;i < size_src;i++)//the loop for advancing the copying process
{
dst[i] = src[i];
}
while (i<size_dst)
{
dst[i] = dst[i++];
if (dst[i] = dst[i++])//relay on the fact that if the function will find a similar varibale, the tested varibale will be set to 0 and the other one will come out clean in the check
dst[i] = 0;//eliminating the varibale in that specific address
}
}
return dst [i];
but it doesn't seems to work and have no idea where it is going wrong.
any help or clue will be appreciated .
I noticed that you're using sizeof(src) within a function that takes int src[] as a parameter. This is not doing what you think it is doing. In C, the size of arrays is not passed to functions along with the array itself (unlike some other languages you may be familiar with). You will have to pass the actual size as a separate parameter.
Also, some printf() statements will definitely help your debugging efforts. Make sure values are what you think they should be. Hopefully you have access to an interactive debugger, that would probably be really useful for you too.
In C you cannot declare a function that takes a parameter that is an array. When you use an array declarator as a function parameter the type is silently adjusted to the corrsponding pointer type. Any explicit array size (if specified) is discarded.
In other words, when you use this:
int RemoveDup (int src[],int dst[])
it is exactly equivalent to this:
int RemoveDup( int *src, int *dst )
It should now be obvious why sizeof(src)/sizeof(int) doesn't do the calculation that you wanted it to do.
well in fact it is possible to make a function recieve an array and not a pointer (given of course the size of the array is pre-defined).
so you can use:
int RemoveDup(int src[M],int dst[N]){
.
.
.
return whatever;
I will agree though that using pointers is better.
In my opinion you should write a recursive function to do that using of course pointers.
so that the next call is (*src+1) so you look at the next cell.
the exit condition is then:
if (sizeof(src) == 0) {
//exit recursion statement.
}
I am working with a 2-dimensional array of structs which is a part of another struct. It's not something I've done a lot with so I'm having a problem. This function ends up failing after getting to the "test" for-loop near the end. It prints out one line correctly before it seg faults.
The parts of my code which read data into a dummy 2-d array of structs works just fine, so it must be my assigning array to be part of another struct (the imageStruct).
Any help would be greatly appreciated!
/*the structure of each pixel*/
typedef struct
{
int R,G,B;
}pixelStruct;
/*data for each image*/
typedef struct
{
int height;
int width;
pixelStruct *arr; /*pointer to 2-d array of pixels*/
} imageStruct;
imageStruct ReadImage(char * filename)
{
FILE *image=fopen(filename,"r");
imageStruct thisImage;
/*get header data from image*/
/*make a 2-d array of of pixels*/
pixelStruct imageArr[thisImage.height][thisImage.width];
/*Read in the image. */
/*I know this works because I after storing the image data in the
imageArr array, I printed each element from the array to the
screen.*/
/*so now I want to take the array called imageArr and put it in the
imageStruct called thisImage*/
thisImage.arr = malloc(sizeof(imageArr));
//allocate enough space in struct for the image array.
*thisImage.arr = *imageArr; /*put imageArr into the thisImage imagestruct*/
//test to see if assignment worked: (this is where it fails)
for (i = 0; i < thisImage.height; i++)
{
for (j = 0; j < thisImage.width; j++)
{
printf("\n%d: R: %d G: %d B: %d\n", i ,thisImage.arr[i][j].R,
thisImage.arr[i][j].G, thisImage.arr[i][j].B);
}
}
return thisImage;
}
(In case you are wondering why I am using a dummy array in the first place, well it's because when I started writing this code, I couldn't figure out how to do what I am trying to do now.)
EDIT: One person suggested that I didn't initialize my 2-d array correctly in the typedef for the imageStruct. Can anyone help me correct this if it is indeed the problem?
You seem to be able to create variable-length-arrays, so you're on a C99 system, or on a system that supports it. But not all compilers support those. If you want to use those, you don't need the arr pointer declaration in your struct. Assuming no variable-length-arrays, let's look at the relevant parts of your code:
/*data for each image*/
typedef struct
{
int height;
int width;
pixelStruct *arr; /*pointer to 2-d array of pixels*/
} imageStruct;
arr is a pointer to pixelStruct, and not to a 2-d array of pixels. Sure, you can use arr to access such an array, but the comment is misleading, and it hints at a misunderstanding. If you really wish to declare such a variable, you would do something like:
pixelStruct (*arr)[2][3];
and arr would be a pointer to an "array 2 of array 3 of pixelStruct", which means that arr points to a 2-d array. This isn't really what you want. To be fair, this isn't what you declare, so all is good. But your comment suggests a misunderstanding of pointers in C, and that is manifested later in your code.
At this point, you will do well to read a good introduction to arrays and pointers in C, and a really nice one is C For Smarties: Arrays and Pointers by Chris Torek. In particular, please make sure you understand the first diagram on the page and everything in the definition of the function f there.
Since you want to be able to index arr in a natural way using "column" and "row" indices, I suggest you declare arr as a pointer to pointer. So your structure becomes:
/* data for each image */
typedef struct
{
int height;
int width;
pixelStruct **arr; /* Image data of height*width dimensions */
} imageStruct;
Then in your ReadImage function, you allocate memory you need:
int i;
thisImage.arr = malloc(thisImage.height * sizeof *thisImage.arr);
for (i=0; i < thisImage.height; ++i)
thisImage.arr[i] = malloc(thisImage.width * sizeof *thisImage.arr[i]);
Note that for clarity, I haven't done any error-checking on malloc. In practice, you should check if malloc returned NULL and take appropriate measures.
Assuming all the memory allocation succeeded, you can now read your image in thisImage.arr (just like you were doing for imageArr in your original function).
Once you're done with thisImage.arr, make sure to free it:
for (i=0; i < thisImage.height; ++i)
free(thisImage.arr[i]);
free(thisImage.arr);
In practice, you will want to wrap the allocation and deallocation parts above in their respective functions that allocate and free the arr object, and take care of error-checking.
I don't think sizeof imageArr works as you expect it to when you're using runtime-sized arrays. Which, btw, are a sort of "niche" C99 feature. You should add some printouts of crucial values, such as that sizeof to see if it does what you think.
Clearer would be to use explicit allocation of the array:
thisImage.arr = malloc(thisImage.width * thisImage.height * sizeof *thisImage.arr);
I also think that it's hard (if even possible) to implement a "true" 2D array like this. I would recommend just doing the address computation yourself, i.e. accessing a pixel like this:
unsigned int x = 3, y = 1; // Assume image is larger.
print("pixel at (%d,%d) is r=%d g=%d b=%d\n", x, y, thisImage.arr[y * thisImage.width + x]);
I don't see how the required dimension information can be associated with an array at run-time; I don't think that's possible.
height and width are undefined; you might want to initialise them first, as in
thisImage.height = 10; thisImage.width = 20;
also,
what is colorRGB?
*thisImage.arr = *imageArr; /*put imageArr into the thisImage imagestruct*
This won't work. You have to declare arr as colorRGB **, allocate it accordingly, etc.
it looks like you are trying to copy array by assignment.
You cannot use simple assignment operator to do that, you have to use some function to copy things, for example memcpy.
*thisImage.arr = *imageArr;
thisimage.arr[0] = imagearr[0];
The above statements are doing the same thing.
However this is not most likely what causes the memory corruption
since you are working with two dimensional arrays, do make sure you initialize them correctly.
Looking at the code, should not even compile: the array is declared as one-dimensional in your image structure but you refer to as two-dimensional?