Is there a way to get the length of an Array when I only know a pointer pointing to the Array?
See the following example
int testInt[3];
testInt[0] = 0;
testInt[1] = 1;
testInt[2] = 1;
int* point;
point = testInt;
Serial.println(sizeof(testInt) / sizeof(int)); // returns 3
Serial.println(sizeof(point) / sizeof(int)); // returns 1
(This is a snipplet from Arduino Code - I'm sorry, I don't "speak" real C).
The easy answer is no, you cannot. You'll probably want to keep a variable in memory which stores the amount of items in the array.
And there's a not-so-easy answer. There's a way to determine the length of an array, but for that you would have to mark the end of the array with another element, such as -1. Then just loop through it and find this element. The position of this element is the length. However, this won't work with your current code.
Pick one of the above.
Also doing an Arduino project here...
Everybody on the internet seems to insist it's impossible to do this...
and yet the oldest trick in the book seems to work just fine with null terminated arrays...
example for char pointer:
int getSize(char* ch){
int tmp=0;
while (*ch) {
*ch++;
tmp++;
}return tmp;}
magic...
You can infer the length of an array if you have an array variable.
You cannot infer the length of an array if you have just a pointer to it.
You cannot and you should not attempt deduce array length using pointer arithmetic
if in C++ use vector class
You can if you point the the whole array and NOT point to the first element like:
int testInt[3];
int (*point)[3];
point = testInt;
printf( "number elements: %lu", (unsigned long)(sizeof*point/sizeof**point) );
printf( "whole array size: %lu", (unsigned long)(sizeof*point) );
Is there a way to get the length of an Array when I only know a pointer pointing to the Array?
Technically yes, there is a way when code has a true pointer to an array as the array size is in the type as with int (*array_pointer)[3].
This differs from OP's code as the pointer point is not a pointer to an array, but a pointer to an int.
The line point = testInt; converts the array testInt to the address of the first element of the array (which is an int *) and assigns that to point. Thus the array size info is lost.
int testInt[3];
testInt[0] = 0;
testInt[1] = 1;
testInt[2] = 1;
int* point;
point = testInt; // Get the address of testInt[0]
int (*array_pointer)[3] = &testInt; // Get the address of the array
printf("%zu\n", sizeof(testInt) / sizeof(int));
printf("%zu\n", sizeof(point) / sizeof(int));
printf("%zu\n", sizeof(*point) / sizeof(int));
printf("%zu\n", sizeof(*array_pointer) / sizeof(int));
printf("%p\n", (void *) testInt);
printf("%p\n", (void *) point);
printf("%p\n", (void *) array_pointer);
Sample output
3
2
1
3
0xffffcbc4
0xffffcbc4
0xffffcbc4
Pointers point and array_pointer both have values that point to the same location in memory, but the pointers differ in type.
With C99 or later that support variable length arrays, code could have been the below and achieved similar results without explicitly coding a 3 in the pointer definition.
int (*array_pointer_vla)[sizeof testInt/sizeof testInt[0]] = &testInt;
printf("%zu\n", sizeof(*array_pointer_vla) / sizeof(int));
Output
3
I see now see similarities to #user411313 answer. Perhaps the deeper explanation and VLA discussion will be useful.
Related
I have currently trouble understanding the following scenario:
I have a multidimensional array of Strings and I want to address it by using pointers only but I always get a Segmentation Fault when using the array annotation on the pointer. This is just an example code I want to use the 3D array in a pthread so I want to pass it in via a structure as a pointer but it just doesn't work and I would like to know why? I thought pointers and arrays are functionally equivalent? Here is the sample code:
#include <stdio.h>
void func(unsigned char ***ptr);
int main() {
// Image of dimension 10 times 10
unsigned char image[10][10][3];
unsigned char ***ptr = image;
memcpy(image[0][0], "\120\200\12", 3);
// This works as expected
printf("Test: %s", image[0][0]);
func(image);
return 0;
}
void func(unsigned char ***ptr) {
// But here I get a Segmentation Fault but why??
printf("Ptr: %s", ptr[0][0]);
}
Thanks in advance for your help :)
I think maybe strdup confuses the issue. Pointers and arrays are not always equivalent. Let me try to demonstrate. I always avoid actual multi-dimension arrays, so I may make a mistake here, but:
int main()
{
char d3Array[10][10][4]; //creates a 400-byte contiguous memory area
char ***d3Pointer; //a pointer to a pointer to a pointer to a char.
int i,j;
d3Pointer = malloc(sizeof(char**) * 10);
for (i = 0; i < 10; ++i)
{
d3Pointer[i] = malloc(sizeof(char*) * 10);
for (j = 0; j < 4; ++j)
{
d3Pointer[i][j] = malloc(sizeof(char) * 4);
}
}
//this
d3Pointer[2][3][1] = 'a';
//is equivalent to this
char **d2Pointer = d3Pointer[2];
char *d1Pointer = d2Pointer[3];
d1Pointer[1] = 'a';
d3Array[2][3][1] = 'a';
//is equivalent to
((char *)d3Array)[(2 * 10 * 4) + (3 * 4) + (1)] = 'a';
}
Generally, I use the layered approach. If I want contiguous memory, I handle the math myself..like so:
char *psuedo3dArray = malloc(sizeof(char) * 10 * 10 * 4);
psuedo3dArray[(2 * 10 * 4) + (3 * 4) + (1)] = 'a';
Better yet, I use a collection library like uthash.
Note that properly encapsulating your data makes the actual code incredibly easy to read:
typedef unsigned char byte_t;
typedef struct
{
byte_t r;
byte_t g;
byte_t b;
}pixel_t;
typedef struct
{
int width;
int height;
pixel_t * pixelArray;
}screen_t;
pixel_t *getxyPixel(screen_t *pScreen, int x, int y)
{
return pScreen->pixelArray + (y*pScreen->width) + x;
}
int main()
{
screen_t myScreen;
myScreen.width = 1024;
myScreen.height = 768;
myScreen.pixelArray = (pixel_t*)malloc(sizeof(pixel_t) * myScreen.height * myScreen.width);
getxyPixel(&myScreen, 150, 120)->r = 255;
}
In C, you should allocate space for your 2D array one row at a time. Your definition of test declares a 10 by 10 array of char pointers, so you don't need to call malloc for it. But to store a string you need to allocate space for the string. Your call to strcpy would crash. Use strdup instead. One way to write your code is as follows.
char ***test = NULL;
char *ptr = NULL;
test = malloc(10 * sizeof(char **));
for (int i = 0; i < 10; i++) {
test[i] = malloc(10 * sizeof(char *));
}
test[0][0] = strdup("abc");
ptr = test[0][0];
printf("%s\n", ptr);
test[4][5] = strdup("efg");
ptr = test[4][5];
printf("%s\n", ptr);
Alternatively, if you want to keep your 10 by 10 definition, you could code it like this:
char *test[10][10];
char *ptr = NULL;
test[0][0] = strdup("abc");
ptr = test[0][0];
printf("%s\n", ptr);
test[4][5] = strdup("efg");
ptr = test[4][5];
printf("%s\n", ptr);
Your problem is, that a char[10][10][3] is something very different from a char***: The first is an array of arrays of arrays, the later is a pointer to a pointer to a pointer. The confusions arises because both can be dereferenced with the same syntax. So, here is a bit of an explanation:
The syntax a[b] is nothing but a shorthand for *(a + b): First you perform pointer arithmetic, then you dereference the resulting pointer.
But, how come you can use a[b] when a is an array instead of a pointer? Well, because...
Arrays decay into pointers to their first element: If you have an array declared like int array[10], saying array + 3 results in array decaying to a pointer of type int*.
But, how does that help to evaluate a[b]? Well, because...
Pointer arithmetic takes the size of the target into account: The expression array + 3 triggers a calculation along the lines of (size_t)array + 3*sizeof(*array). In our case, the pointer that results from the array-pointer-decay points to an int, which has a size, say 4 bytes. So, the pointer is incremented by 3*4 bytes. The result is a pointer that points to the fourths int in the array, the first three elements are skipped by the pointer arithmetic.
Note, that this works for arrays of any element type. Arrays can contain bytes, or integers, or floats, or structs, or other arrays. The pointer arithmetic is the same.
But, how does that help us with multidimensional arrays? Well, because...
Multidimensional arrays are just 1D arrays that happen to contain arrays as elements: When you declare an array with char image[256][512]; you are declaring a 1D array of 256 elements. These 256 elements are all arrays of 512 characters, each. Since the sizeof(char) == 1, the size of an element of the outer array is 512*sizeof(char) = 512, and, since we have 256 such arrays, the total size of image is 256*512. Now, I can declare a 3D array with char animation[24][256][512];...
So, going back to your example that uses
char image[10][10][3]
what happens when you say image[1][2][1] is this: The expression is equivalent to this one:
*(*(*(image + 1) + 2) + 3)
image being of type char[10][10][3] decays into a pointer to its first element, which is of type char(*)[10][3] The size of that element is 10*3*1 = 30 bytes.
image + 1: Pointer arithmetic is performed to add 1 to the resulting pointer, which increments it by 30 bytes.
*(image + 1): The pointer is dereferenced, we are now talking directly about the element, which is of type char[10][3].
This array again decays into a pointer to its first element, which is of type char(*)[3]. The size of the element is 3*1 = 3. This pointer points at the same byte in memory as the pointer that resulted from step 2. The only difference is, that it has a different type!
*(image + 1) + 2: Pointer arithmetic is performed to add 2 to the resulting pointer, which increments it by 2*3 = 6 bytes. Together with the increment in step 2, we now have an offset of 36 bytes, total.
*(*(image + 1) + 2): The pointer is dereferenced, we are now talking directly about the element, which is of type char[3].
This array again decays into a pointer to its first element, which is of type char*. The size of the element is now just a single byte. Again, this pointer has the same value as the pointer resulting from step 5, but a different type.
*(*(image + 1) + 2) + 1: Pointer arithmetic again, adding 1*1 = 1 bytes to the total offset, which increases to 37 bytes.
*(*(*(image + 1) + 2) + 1): The pointer is dereferenced the last time, we are now talking about the char at an offset of 37 bytes into the image.
So, what's the difference to a char***? When you dereference a char***, you do not get any array-pointer-decay. When you try to evaluate the expression pointers[1][2][1] with a variable declared as
char*** pointers;
the expression is again equivalent to:
*(*(*(pointers + 1) + 2) + 3)
pointers is a pointer, so no decay happens. Its type is char***, and it points to a value of type char**, which likely has a size of 8 bytes (assuming a 64 bit system).
pointers + 1: Pointer arithmetic is performed to add 1 to the resulting pointer, which increments it by 1*8 = 8 bytes.
*(pointers + 1): The pointer is dereferenced, we are now talking about the pointer value that is found in memory at an offset of 8 bytes of where pointers points.
Further steps depending on what actually happened to be stored at pointers[1]. These steps do not involve any array-pointer-decay, and thus load pointers from memory instead.
You see, the difference between a char[10][10][3] and a char*** is profound. In the first case, the array-pointer-decay transforms the process into a pure offset computation into a multidimensional array. In the later case, we repeatedly load pointers from memory when accessing elements, all we ever have are 1D arrays of pointers. And it's all down to the types of pointers!
Is there a way to get the length of an Array when I only know a pointer pointing to the Array?
See the following example
int testInt[3];
testInt[0] = 0;
testInt[1] = 1;
testInt[2] = 1;
int* point;
point = testInt;
Serial.println(sizeof(testInt) / sizeof(int)); // returns 3
Serial.println(sizeof(point) / sizeof(int)); // returns 1
(This is a snipplet from Arduino Code - I'm sorry, I don't "speak" real C).
The easy answer is no, you cannot. You'll probably want to keep a variable in memory which stores the amount of items in the array.
And there's a not-so-easy answer. There's a way to determine the length of an array, but for that you would have to mark the end of the array with another element, such as -1. Then just loop through it and find this element. The position of this element is the length. However, this won't work with your current code.
Pick one of the above.
Also doing an Arduino project here...
Everybody on the internet seems to insist it's impossible to do this...
and yet the oldest trick in the book seems to work just fine with null terminated arrays...
example for char pointer:
int getSize(char* ch){
int tmp=0;
while (*ch) {
*ch++;
tmp++;
}return tmp;}
magic...
You can infer the length of an array if you have an array variable.
You cannot infer the length of an array if you have just a pointer to it.
You cannot and you should not attempt deduce array length using pointer arithmetic
if in C++ use vector class
You can if you point the the whole array and NOT point to the first element like:
int testInt[3];
int (*point)[3];
point = testInt;
printf( "number elements: %lu", (unsigned long)(sizeof*point/sizeof**point) );
printf( "whole array size: %lu", (unsigned long)(sizeof*point) );
Is there a way to get the length of an Array when I only know a pointer pointing to the Array?
Technically yes, there is a way when code has a true pointer to an array as the array size is in the type as with int (*array_pointer)[3].
This differs from OP's code as the pointer point is not a pointer to an array, but a pointer to an int.
The line point = testInt; converts the array testInt to the address of the first element of the array (which is an int *) and assigns that to point. Thus the array size info is lost.
int testInt[3];
testInt[0] = 0;
testInt[1] = 1;
testInt[2] = 1;
int* point;
point = testInt; // Get the address of testInt[0]
int (*array_pointer)[3] = &testInt; // Get the address of the array
printf("%zu\n", sizeof(testInt) / sizeof(int));
printf("%zu\n", sizeof(point) / sizeof(int));
printf("%zu\n", sizeof(*point) / sizeof(int));
printf("%zu\n", sizeof(*array_pointer) / sizeof(int));
printf("%p\n", (void *) testInt);
printf("%p\n", (void *) point);
printf("%p\n", (void *) array_pointer);
Sample output
3
2
1
3
0xffffcbc4
0xffffcbc4
0xffffcbc4
Pointers point and array_pointer both have values that point to the same location in memory, but the pointers differ in type.
With C99 or later that support variable length arrays, code could have been the below and achieved similar results without explicitly coding a 3 in the pointer definition.
int (*array_pointer_vla)[sizeof testInt/sizeof testInt[0]] = &testInt;
printf("%zu\n", sizeof(*array_pointer_vla) / sizeof(int));
Output
3
I see now see similarities to #user411313 answer. Perhaps the deeper explanation and VLA discussion will be useful.
I have code which already works but am trying to extend it.
unsigned char **data_ptr;
Allocate memory for the first "array"
data_ptr = (unsigned char **)malloc(sizeof(unsigned char **) * no_of_rows);
Then in a loop initialize each row
data_ptr[index] = (unsigned char *)malloc(sizeof(unsigned char*), rowsize));
I then pass the address of my array to a library function. It works fine if I just pass the start of a row...
LibFunction( info_ptr, &data_ptr[index] ) //OK
But I need to pass the address of where in a row I want the function to begin writing data.
These both compile but fail in operation
LibFunction( info_ptr,(unsigned char **)data_ptr[index] + 1);
or..
LibFunction( info_ptr,(unsigned char **)data_ptr[index][1]);
LibFunction is of the form
LibFunction(..., unsigned char **)
I'm allocating more memory than I need with rowsize so I don't think I'm overrunning the array. As I stated, the code works fine if I pass it the start of a row but bugs out if I
try to pass any other element. There may be something else wrong but I need to know first if my syntax is ok.
Can't find anything else on the net as regards passing the address of single element of dynamic 2d array.
LibFunction( info_ptr,(unsigned char **)data_ptr[index] + 1);
is wrong because data_ptr is an unsigned char **, so data_ptr[index] is an unsigned char *. Leave out the cast and correct the function you're calling, it should accept an unsigned char *.
Some corrections in your program, observed from the top few lines
Since,
unsigned char **data_ptr; // a pointer to a char pointer
get the sizeof(char*) and always avoid typecasting the pointer returned by malloc()
data_ptr = malloc(sizeof(unsigned char *) * no_of_rows);
And for doing the allocation for the rows,
data_ptr[index] = (unsigned char *)malloc(sizeof(unsigned char*)* rowsize));
To pass the address of where in a row you want the function to begin writing data, change the function signature as
LibFunction(..., unsigned char *)
It should be LibFunction(&data_ptr[row][start_here]), exactly the same as if it was just an unsigned char[ROWS][COLUMNS];.
In general, it is my experience that if you think you require casts in modern-day C, it is probable that you are muddled up with what you are trying to do. A nice read is a comment on a post by Linus Torvalds on /. on this kind of stuff.
You're not allocating room for no_of_rows pointers to pointers; there's an asterisk too many in there. Also, you really [shouldn't cast the return value of malloc(), in C][1].
Your first allocation should be:
data_ptr = malloc(no_of_rows * sizeof *data_ptr);
But I need to pass the address of where in a row I want the function to begin writing data
So let's start simple, to make an array the correct size, forget trying to get the sizeof a complex type, we can simply do this:
unsigned char **data_ptr;
data_ptr = malloc(sizeof(data_ptr) * no_of_rows); //Just sizeof your var
Now you've got the correct memory malloc'd next you can malloc the memory for the rest easily:
for(index = 0; index < no_of_rows; index++)
data_ptr[index] = malloc(sizeof(unsigned char*) * rowsize);
Last point, now that we've got all that set up, you should initialize your array:
for(index = 0; index < no_of_rows; index++)
for(index2 = 0; index2 < rowsize; index2++)
data_ptr[index][index2] = 0;
As for your function, you want it to take a "portion" of an array, so we need it to take an array and a size (the length of the array to initialize):
void LibFunction(unsigned char data[], int size);
Then we're your ready to store some data it's as easy as:
LibFunction(&data_ptr[1][2], 3); // store data in second row, 3rd column, store
// three values.
You can do something like this:
unsigned char* ptr = &data[0][1];
LibFunction(info_ptr, &ptr);
I want to create an integer pointer p, allocate memory for a 10-element array, and then fill each element with the value of 5. Here's my code:
//Allocate memory for a 10-element integer array.
int array[10];
int *p = (int *)malloc( sizeof(array) );
//Fill each element with the value of 5.
int i = 0;
printf("Size of array: %d\n", sizeof(array));
while (i < sizeof(array)){
*p = 5;
printf("Current value of array: %p\n", *p);
*p += sizeof(int);
i += sizeof(int);
}
I've added some print statements around this code, but I'm not sure if it's actually filling each element with the value of 5.
So, is my code working correctly? Thanks for your time.
First:
*p += sizeof(int);
This takes the contents of what p points to and adds the size of an integer to it. That doesn't make much sense. What you probably want is just:
p++;
This makes p point to the next object.
But the problem is that p contains your only copy of the pointer to the first object. So if you change its value, you won't be able to access the memory anymore because you won't have a pointer to it. (So you should save a copy of the original value returned from malloc somewhere. If nothing else, you'll eventually need it to pass to free.)
while (i < sizeof(array)){
This doesn't make sense. You don't want to loop a number of times equal to the number of bytes the array occupies.
Lastly, you don't need the array for anything. Just remove it and use:
int *p = malloc(10 * sizeof(int));
For C, don't cast the return value of malloc. It's not needed and can mask other problems such as failing to include the correct headers. For the while loop, just keep track of the number of elements in a separate variable.
Here's a more idiomatic way of doing things:
/* Just allocate the array into your pointer */
int arraySize = 10;
int *p = malloc(sizeof(int) * arraySize);
printf("Size of array: %d\n", arraySize);
/* Use a for loop to iterate over the array */
int i;
for (i = 0; i < arraySize; ++i)
{
p[i] = 5;
printf("Value of index %d in the array: %d\n", i, p[i]);
}
Note that you need to keep track of your array size separately, either in a variable (as I have done) or a macro (#define statement) or just with the integer literal. Using the integer literal is error-prone, however, because if you need to change the array size later, you need to change more lines of code.
sizeof of an array returns the number of bytes the array occupies, in bytes.
int *p = (int *)malloc( sizeof(array) );
If you call malloc, you must #include <stdlib.h>. Also, the cast is unnecessary and can introduce dangerous bugs, especially when paired with the missing malloc definition.
If you increment a pointer by one, you reach the next element of the pointer's type. Therefore, you should write the bottom part as:
for (int i = 0;i < sizeof(array) / sizeof(array[0]);i++){
*p = 5;
p++;
}
*p += sizeof(int);
should be
p += 1;
since the pointer is of type int *
also the array size should be calculated like this:
sizeof (array) / sizeof (array[0]);
and indeed, the array is not needed for your code.
Nope it isn't. The following code will however. You should read up on pointer arithmetic. p + 1 is the next integer (this is one of the reasons why pointers have types). Also remember if you change the value of p it will no longer point to the beginning of your memory.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define LEN 10
int main(void)
{
/* Allocate memory for a 10-element integer array. */
int array[LEN];
int i;
int *p;
int *tmp;
p = malloc(sizeof(array));
assert(p != NULL);
/* Fill each element with the value of 5. */
printf("Size of array: %d bytes\n", (int)sizeof(array));
for(i = 0, tmp = p; i < LEN; tmp++, i++) *tmp = 5;
for(i = 0, tmp = p; i < LEN; i++) printf("%d\n", tmp[i]);
free(p);
return EXIT_SUCCESS;
}
//Allocate memory for a 10-element integer array.
int array[10];
int *p = (int *)malloc( sizeof(array) );
At this point you have allocated twice as much memory -- space for ten integers in the array allocated on the stack, and space for ten integers allocated on the heap. In a "real" program that needed to allocate space for ten integers and stack allocation wasn't the right thing to do, the allocation would be done like this:
int *p = malloc(10 * sizeof(int));
Note that there is no need to cast the return value from malloc(3). I expect you forgot to include the <stdlib> header, which would have properly prototyped the function, and given you the correct output. (Without the prototype in the header, the C compiler assumes the function would return an int, and the cast makes it treat it as a pointer instead. The cast hasn't been necessary for twenty years.)
Furthermore, be vary wary of learning the habit sizeof(array). This will work in code where the array is allocated in the same block as the sizeof() keyword, but it will fail when used like this:
int foo(char bar[]) {
int length = sizeof(bar); /* BUG */
}
It'll look correct, but sizeof() will in fact see an char * instead of the full array. C's new Variable Length Array support is keen, but not to be mistaken with the arrays that know their size available in many other langauges.
//Fill each element with the value of 5.
int i = 0;
printf("Size of array: %d\n", sizeof(array));
while (i < sizeof(array)){
*p = 5;
*p += sizeof(int);
Aha! Someone else who has the same trouble with C pointers that I did! I presume you used to write mostly assembly code and had to increment your pointers yourself? :) The compiler knows the type of objects that p points to (int *p), so it'll properly move the pointer by the correct number of bytes if you just write p++. If you swap your code to using long or long long or float or double or long double or struct very_long_integers, the compiler will always do the right thing with p++.
i += sizeof(int);
}
While that's not wrong, it would certainly be more idiomatic to re-write the last loop a little:
for (i=0; i<array_length; i++)
p[i] = 5;
Of course, you'll have to store the array length into a variable or #define it, but it's easier to do this than rely on a sometimes-finicky calculation of the array length.
Update
After reading the other (excellent) answers, I realize I forgot to mention that since p is your only reference to the array, it'd be best to not update p without storing a copy of its value somewhere. My little 'idiomatic' rewrite side-steps the issue but doesn't point out why using subscription is more idiomatic than incrementing the pointer -- and this is one reason why the subscription is preferred. I also prefer the subscription because it is often far easier to reason about code where the base of an array doesn't change. (It Depends.)
//allocate an array of 10 elements on the stack
int array[10];
//allocate an array of 10 elements on the heap. p points at them
int *p = (int *)malloc( sizeof(array) );
// i equals 0
int i = 0;
//while i is less than 40
while (i < sizeof(array)){
//the first element of the dynamic array is five
*p = 5;
// the first element of the dynamic array is nine!
*p += sizeof(int);
// incrememnt i by 4
i += sizeof(int);
}
This sets the first element of the array to nine, 10 times. It looks like you want something more like:
//when you get something from malloc,
// make sure it's type is "____ * const" so
// you don't accidentally lose it
int * const p = (int *)malloc( 10*sizeof(int) );
for (int i=0; i<10; ++i)
p[i] = 5;
A ___ * const prevents you from changing p, so that it will always point to the data that was allocated. This means free(p); will always work. If you change p, you can't release the memory, and you get a memory leak.
in the following snippet I wish the function accept a double pointer(2D array) which can be in any data type(in this case, integer), and use memcpy to copy one element at a time of the array to another variable. It passed the compiler but still shows an access violation.
I looked everywhere around the forum but still can't get this right.
Any tips are appreciated. I am nearly devastated by the complexity of C.
void ShowImg(void **ptr, IplImage *sample, char window_name[])
{
int value;
IplImage *sml_img= cvCreateImage(cvSize(sample->width,sample->height),IPL_DEPTH_8U, 1);
for(int j=0; j<sample->height; j++)
for(int i=0; i<sample->width; i++){
memcpy(&value, ptr+i*sizeof(int)+j*sample->width*sizeof(int), sizeof(int));
((uchar *)(sml_img->imageData + sml_img->widthStep*j))[i] = value;
printf("%d,%d\n", i, j);
}
cvNamedWindow(window_name);
cvShowImage(window_name, sml_img);
cvWaitKey(0);
cvDestroyWindow(window_name);
cvReleaseImage(&sml_img);
}
I think there's a mistake here: ptr+i*sizeof(int) since ptr is of type void** ptr+1 is the next element, meaning ptr+sizeof(void*), why would you multiply it by sizeof(int)?
for example:
ptr = 0x00000000,
sizeof(void*) = 4,
sizeof(int) = 4
||
\/
ptr+1 = 0x00000004.
ptr+1*sizeof(int) = 0x00000010.
and I don't think that's what you want. (the same about j*sample->width*sizeof(int))
memcpy(3) is really for copying objects that are larger than the primitive types. You could replace this line:
memcpy(&value, ptr+i*sizeof(int)+j*sample->width*sizeof(int), sizeof(int));
with this line:
value = ptr+i*sizeof(int)+j*sample->width*sizeof(int);
The sizeof(int) scaling is throwing me; you shouldn't need this if your datatypes are known to the compiler at compile time. Why is your array a void ** rather than something more specific, which the compiler could work with? (int ** would be a good first start, but I'm not very good at multidimensional arrays in C, so I'm not positive this would be a better replacement. But I do dislike what you have now. :)