The problem is that you are not assigning ptr to point at anything, so it points to random memory, and any access of ptr[index] is undefined behavior.
Changing the declaration of ptr like Jonathan's answer suggested is the safest option, eg:
typedef struct{
int size;
int* ptr[1]; // or 0 if your compiler supports it
}foo;
int main()
{
foo *var;
var = malloc(offsetof(foo, ptr));
if (var) {
var->size = 0;
...
}
foo *newvar = realloc(var, offsetof(foo, ptr) + (2 * sizeof(int*)));
if (newvar) {
var = newvar;
var->size = 2;
int a = 3, b = 6;
var->ptr[0] = &a; // <-- OK!
var->ptr[1] = &b; // <-- OK!
printf("%d %d\n", *(var->ptr[0]), *(var->ptr[1]));
}
free(var);
return 0;
}
But, if for whatever reason, you can't change the declaration of ptr (foo is used with an existing API, for instance), then you can do this instead:
typedef struct{
int size;
int **ptr;
}foo;
int main()
{
foo *var = malloc(sizeof(foo));
if (var) {
var->size = 0;
var->ptr = NULL; // <-- add this!
...
}
foo *newvar = realloc(var, sizeof(foo) + (2 * sizeof(int*)));
if (newvar) {
var = newvar;
var->size = 2;
var->ptr = (int**)(var + 1); // <-- add this!
int a = 3, b = 6;
var->ptr[0] = &a; // <-- OK!
var->ptr[1] = &b; // <-- OK!
printf("%d %d\n", *(var->ptr[0]), *(var->ptr[1]));
}
free(var);
return 0;
}
In this latter case, make sure you do the same ptr assignment every time you want to (re)allocate var. I would wrap that logic in a set of helper functions, eg:
typedef struct{
int size;
int **ptr;
}foo;
foo* createFoo(int size)
{
foo *var = malloc(sizeof(foo) + (size * sizeof(int*)));
if (var) {
var->size = size;
var->ptr = (int**)(var + 1);
}
return var;
}
foo* resizeFoo(foo **var, int newSize)
{
foo *newvar = realloc(*var, sizeof(foo) + (newSize * sizeof(int*)));
if (newvar) {
newvar->size = newSize;
newvar->ptr = (int**)(newvar + 1);
*var = newvar;
}
return newvar;
}
int main()
{
foo *var = createFoo(0);
...
if (resizeFoo(&var, 2)) {
int a = 3, b = 6;
var->ptr[0] = &a; // <-- OK!
var->ptr[1] = &b; // <-- OK!
printf("%d %d\n", *(var->ptr[0]), *(var->ptr[1]));
}
free(var);
return 0;
}
ptrfield.ptr(that is what the+ 2 * sizeof(int*)is for), he just doesn't assignptrto point at that memory