Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 24 days ago.
Improve this question
I declared a pointer like this
point *points = malloc(numPoints * sizeof(point));
how do i assign to pointSend the points pulled from the pointer point.
By supplying offset and numpoint where numpoint is the number of points, offset tells me where to start getting them from
point *pointsSend = malloc(numPoints[i] * sizeof(point)); pointsSend=/*offset & numpoint
I haven't found any solution even if I think it's trivial.
It's not clear what you want.
Do you want a copy of a subset of the array pointed by points?
points
+---------+ +---------+--- ---+---------+---------+----
| ------->| | ... | | | ...
+---------+ +---------+--- ---+---------+---------+----
| |
copy copy
| |
newpoints v v
+---------+ +---------+---------+
| ------------------------->| | |
+---------+ +---------+---------+
size_t offset = ...;
size_t n = ...;
size_t bytes = n * sizeof( point );
point *newpoints = malloc( bytes );
if ( !newpoints ) {
...
}
memcpy( newpoints, points + offset, bytes );
...
free( newpoints );
newpoints[ x ] is a copy of points[ x + offset ].
Or maybe you don't need a copy.
points
+---------+ +---------+--- ---+---------+---------+----
| ------->| | ... | | | ...
+---------+ +---------+--- ---+---------+---------+----
^
newpoints |
+---------+ |
| -------------------------------+
+---------+
size_t offset = ...;
size_t n = ...;
point *newpoints = points + offset;
...
newpoints[ x ] is the same as points[ x + offset ].
For this version, make sure not to free points while still using newpoints!
Related
If we create a char array:
char strings[3][10] = {"Apple","Banana","Grape"};
and a pointer of type char:
char *pstrings[] = {"Apple","Banana","Grape"};
If we print the addresses of the elements, the char array elements will be 10 bytes apart and the elements of the pointer don't seem to follow one another.
How does your program know where to find the next element of the char pointer if the elements do not follow each other in memory?
Well you are initializing the array of char* with that information.
In fact char*[] contains individual char* pointing to the respective string literal. How does it come? Well "abc" is basically a null terminated char array that decays into pointer to first element of the array which is 'a' and now if that is known it isn't hard to access them. The addresses are being stored basically. In the second case you are initializing the char* array wit those value. Those string literals need not be from contiguous memory.
+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+
ADDRESS |Random | |Random | |Random |
+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+
|A|p|p|l|e| |B|a|n|a|n|a| |G|r|a|p|e|
+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+
\ | /
\ | /
\ | /
+-+-+-+-+-+-+-+-+-+
| 0 | 1 | 2 |
+-+-+-+-+-+-+-+-+-+
That's why you got different values when you printed strings[0], strings[1] etc.
Program just uses the initialized values that is stored in pstrings and that contains the address of those string literals. That's how we use it.
In the first case, same content as your string literals - we are initializing them in the char array which are in turn contiguous.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
ADDRESS |strings + 0 |strings + 10 |strings + 20 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
|A|p|p|l|e| | | | | |B|a|n|a|n|a| | | | |G|r|a|p|e| | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| 0 | 1 | 2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
As a result we can have those modifiable strings each being stored in an array of 10 chars. char p[]="abc"; is equivalent to char p[]={'a','b','c','\0'} same happens here.
Also know one thing, the second case also the pointer values are stored in contiguous memory.
These wonderful ascii-art explanation is provided by Keine Lust.
I have this piece of code in one library I'm using and I'm wondering what it does, since I'm having problems with memory I suppose this is the reason.
So the piece of code is following:
int new_size = foo->a_size + 10;
foo->a = realloc(foo->a, new_size*sizeof(struct items));
memset(foo->a+foo->a_size, 0, 10);
foo->a is type struct items* and foo->a_size is type int.
First lines reallocate 10 blocks of new memory but now I'm wondering if memset() sets both foo->a and foo->a_size to 0 or should this set blocks from 11-20 to 0 in foo->a?
I have tried to run this code block on its own and receive only Segmentation fault
EDIT:
Question was that does the memset() set both foo->a and foo->a_size to 0 or does it set blocks from offset foo->a_size to 0 in foo->a. The latter assumption was correct but I need to also fix the memset() so the last argument is 10 * sizeof(struct items). I also edited variable names from foo->b to foo->a_size.
You are initializing 10 Bytes in foo->a(pointer) with foo->b(int) offset. In the other words you just initialized appended memory.
Example:
Lets assume foo->a is int* and is pointing to 5 ints continuous block.
+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+
You need 10 ints, so you will realloc that block to size 10 * sizeof(int) Bytes, but appended 5 * sizeof(int) Bytes are uninitialized.
+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | ? | ? | ? | ? | ? |
+---+---+---+---+---+---+---+---+---+---+
So by doing
memset(pointerToFirstByte + Offset, 0, 5 * sizeof(int));
You will init these appended bytes to 0.
+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+---+---+
^---^---^---^---^------ Initialized to 0
The line in question sets 10 bytes starting with an offset by foo->b from foo->a to 0. The offset is in steps the size of the structure items. We don't have enough information to further explain this, but my speculation is that foo->a is a pointer to a dynamically allocated array of the structure and here we are setting the fields of part of it(possibly one element?) to 0.
So these 2 lines increase foo->a by 10 lots of whatever struct items is.
int new_size = foo->b + 10;
foo->a = realloc(foo->a, new_size*sizeof(struct items));
This sets 10 bytes of memory of foo->a offset by foo->b * sizeof(struct items) to 0
memset(foo->a+foo->b, 0, 10);
which isn't probably enough as it's unlikely struct items is just 1 byte in size. What you should be doing is clearly 10 lots of struct items like this.
memset(foo->a+foo->b, 0, 10*sizeof(struct items));
The memset in the code fragment initializes 10 bytes in the newly allocated part of foo->a to 0. There are multiple problems in this code:
You do not test for realloc() failure.
You overwrite foo->a with the return value from realloc(). If realloc() fails, the block previouly pointed to by foo->a is still allocated but potentially unreachable, a memory leak.
The space set to 0 is most probably too small.
Initializing to all bits 0 might not be appropriate for the structure items.
You do not update foo->size.
Here is an improved version:
size_t new_size = foo->a_size + 10;
struct items *newp = realloc(foo->a, new_size * sizeof(*foo->a));
if (newp == NULL) {
// handle the error
} else {
memset(newp + foo->a_size, 0, (new_size - foo->a_size) * sizeof(*foo->a));
foo->a = newp;
foo->a_size = new_size;
}
memset(foo->a+foo->b, 0, 10);
This line sets the 10 Bytes of Foo->a to 0.
foo->a + foo->b is a offset value in it.
I'm trying to print a dynamic 2D array in C, the problem is that with the code it prints fine the first time but if its printed anymore times its missing the bottom row.
This is the code I'm working with:
void display_board( int height, int width, char** gameBoard ) {
int i;
char *rowString;
rowString = malloc(((width*2)+1) * sizeof( char ));
for( i = 0; i < ((height*2) + 1); i++ ){
rowString = *(gameBoard + i);
printf("%s\n",rowString);
}
free(rowString);
}
The game being made is dots and boxes so width and height are the amount of boxes, the arrays are actually allocated as height*2+1 and width*2+1 and is set up to look like this if the height is 2 and width is4, note that the example has all the edges filled in already but normally the edges would just be white spaces:
x-x-x-x-x
| | | | |
x-x-x-x-x
| | | | |
x-x-x-x-x
When I print this the first time it looks like that, but if I try and print it again it looks like this:
x-x-x-x-x
| | | | |
x-x-x-x-x
| | | | |
Any idea on why this is happening?
Before the loop you allocate memory and assign it to the pointer variable rowString. But inside the loop you reassign the variable to point to somewhere else, loosing the original pointer to your allocated memory. Later when you try to free the memory you free the memory in the "2d matrix" instead of the memory you just allocated.
All of this leads to undefined behavior as you then later try to dereference the previously free'd memory (*(gameBoard + i)).
The obvious solution here is to not reassign the pointer, but to copy the string, e.g. with strcpy. Another pretty obvious solution would be to not allocate memory at all, and not even use the rowString variable, as you don't really need it but can use the pointer *(gameBoard + i) directly in your printf call.
This question already has answers here:
What does s[-1] = 0 mean?
(6 answers)
Closed 8 years ago.
I was trying the below code snippet. Please help me in understanding how the o/p is coming as 2? What does p[-2] mean here?
int main(void){
int ary[4] = {1, 2, 3, 6};
int *p = ary + 3;
printf("%d\n", p[-2]);
}
ary is an array of four ints. This will be put in memory like this:
| 1 | 2 | 3 | 6 |
^ ^ ^
| | |
ary p - 2 p
By saying p = ary + 3, you're setting p to the address of the fourth element in the array. So, p is pointing to 6. p[-2] is equal to *(p - 2). That means you point p to the second element in the array, and access its value: 2.
int *p = ary + 3 points to ary[3] so if you move the pointer two steps back you will get ary[1]
|--------|
// / |4 4 4 |
// |--------| 4 |
// / |3 3 3 | 4 |
// |---------|3 | |
// / | 2 2 2 |3 | /
// |---------|2 |__|
// | 1 1 1 |2 | /
// | 1 1 1 |__|
// | 1 1 1 | /
// |_________|
double arr[4][3][3] = {{1,1,1,1,1,1,1,1,1},{2,2,2,2,2,2,2,2,2},{3,3,3,3,3,3,3,3,3},{4,4,4,4,4,4,4,4,4}};
I consider that this array consists of 4 layers.
I want to create pointer to layer of array and traverse through layers of that array using pointer.
I try :
double (*pp1)[sizeof(arr[0]) / sizeof(ar[0][0][0])];
pp1 = arr[0];
and get error from intelIsense:
value of type (double (*)(3) can`t be assigned to double(*)(9)
So if you do:
int i;
double arr[4][3][3] = {{1,1,1,1,1,1,1,1,1},{2,2,2,2,2,2,2,2,2},
{3,3,3,3,3,3,3,3,3},{4,4,4,4,4,4,4,4,4}};
double (*pp3)[3][3];
pp3 = arr;
for (i = 0; i <= 3; i++)
{ printf("pp3 + %d is %f \n", i, ***(pp3 + i));
}
Then you get the desired behavior. The problem with your code is that, just as the compiler is telling you, you are trying to assign a pointer to an array of 9 double (double (*pp1)[sizeof(arr[0] / sizeof(arr[0][0][0])] evaluates to double (*pp1)[9] ), but you need a pointer to an array of 3 of array of 3, which is what you declared with double arr[4][3][3]. From my tests, gcc will accept the double (*pp1)[9] with a compiler warning, which is what I tried to get at in my comment below. Hope that clears things up.
If you want to keep this general, then what you really want is double (*pp3)[sizeof(arr[0]) / sizeof(arr[0][0])][sizeof(arr[0][0]) / sizeof(arr[0][0][0])], which is a bloody nightmare.
EDIT: Forgot a dereference... Should've copy/pasted haha. Also added explanation about the question's code behavior. Fixed as per comments.
Why not simply get the direction of the first element of a given layer?
double *pp1 = &ar[0][0][0];
double *pp2 = &ar[1][0][0];
/* and so on */
While trying to figure out this issue i got some results.
I find out that the following statements raises no errors from compiler
double arr[4][4][9];
double (*pp3)[9];
pp3 = arr[0];
So, is it right to deduce from code above that pointer can be assigned to array only in case if number of elements to which it points is equall to the smallest dimension of array?
update:
I think that pointer can be created on the smallest layer of array only.
Can somebody explain this?