Reputation: 4853
I wrote a program the involved two rows of integers that would periodically swap places. So, what I did was allocate two separate pointers to integers that would model the needed rows. I then placed both of the pointers into a constant pointer array that would easily facilitate the swapping.
The problem I am having was by complete mistake. Take this for example:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char* a = malloc(sizeof(char)*5);
char* temp[] = {a};
int i, h, k = 'a';
for(i = 0; i < 5; i++)
a[i] = k++;
for(i = 0; i < 5; i++)
printf("%c ", temp[0][i]);
free(a);
return 0;
}
With output: a b c d e
IdeOne
I accidentally attempted to access the members of the array contained within the static array by second-order dereferencing: "[][]"
I did not think much of this event because everything compiled and ran perfectly, even giving the expected results at the output. The problem came when I ran a memory analysis and found that I was getting tons of addressing errors and alleged memory leaks.
So, to start the debugging process I wanted to come here and ask why this worked and if it's valid C syntax. I was under the impression that:
temp[0]
Would dereference to char*
, a
. It would then take a further dereference of a
to access its members. Further, I was under the impression that:
temp[row][col]
Is translated to:
*(*(temp + row*col) + col)
at run time. As such, the double dereference of temp[0][i]
should give an offset from temp
and not access a
at all.
What's more interesting is that this:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char* a = malloc(sizeof(char)*5);
char* b = malloc(sizeof(char)*5);
char* temp[] = {a, b};
int i, h, k = 'a', j = 'A';
for(i = 0; i < 5; i++){
a[i] = k++;
b[i] = j++;
}
for(i = 0; i < 5; i++){
for(h = 0; h < 5; h++)
printf("%c ", temp[i][h]);
puts("");
}
free(a);
free(b);
return 0;
}
Does not compile when run at IdeOne. However, this code does compile using Microsoft Visual Studio Professional 2013 and gcc
in c99
mode.
Any ideas or suggestions on how to properly do what I was attempting to do? That is, access members a
and b
that are contained within the static array temp
without using really ugly syntax like:
*(temp[i] + sizeof(char)*h)
Upvotes: 3
Views: 134
Reputation: 3526
You guessed it right when you thought temp[0]
equals a
and temp[1]
equals b
. But wait why are you going beyond that like you are trying to dereference something like temp[2]
? You did not initialize this thing right!
Your program causes undefined behaviour
by accessing memory past the end of the array. The compiler is not always obliged to give you an error message. Check this question.
Upvotes: 1
Reputation: 9680
The C99 standard §6.5.2.1 ¶2 says -
The definition of the subscript operator
[]
is thatE1[E2]
is identical to(*((E1)+(E2)))
Therefore, the expression temp[row][col]
is evaluated as
temp[row][col] --> *((temp[row]) + col) --> *(*(temp + row) + col)
|_______| |
| |
E1 E2
and not as *(*(temp + row*col) + col)
. Please note the difference. Therefore, your first program is fine.
In the second program, the statement
char* temp[] = {a, b};
defines and initializes temp
to be an array of 2
pointers to characters. However, in the for
loop, you access the array as temp[i][h]
and i
ranges from 0
to 4
. Accessing elements out of the bound of an array is undefined behaviour. Therefore, your second program is wrong.
Upvotes: 1
Reputation: 122373
temp[row][col]
is not equivalent to *(*(temp + row*col) + col)
, but actually equivalent to *(*(temp + row) + col)
.
Your second example code is incorrect because temp
is an array of 2 elements, but you are accessing temp[i]
with i
ranges from 0
to 5
.
Upvotes: 3