# Thread: kinda wierd stuff with pointers...

1. ## kinda wierd stuff with pointers...

I'm trying to learn how to do dynamic allocation stuff, so I'm trying to make a program that uses this. I don't get any errors when I compile, and none of the malloc checks print anything, but apparantly the program never gets to my printf line that comes before all the free() calls.
Nothing prints except for the first line.

Code:
#include "windows.h"
#include "stdio.h"
#include "time.h"
#include "math.h"
#include "string.h"

typedef struct UNIT{
void	**p;
int		pS;
}UNIT;

UNIT	**u;
int		uS=10;
int 	l[10];

void main(void){
printf("Only line that prints");
u=malloc(uS*sizeof(UNIT *));
if(u==NULL){
printf("\n\tu=malloc failed");
return;
}
for(l[0]=0;l[0]<uS;l[0]++){
(*u[l[0]]).pS=10;
(*u[l[0]]).p=malloc((*u[l[0]]).pS*sizeof(void *));
if((*u[l[0]]).p==NULL){
printf("\n\t(*u[%d]).p=malloc failed",(l[0]));
continue;
}
for(l[1]=0;l[1]<(*u[l[0]]).pS;l[1]++){
(*u[l[0]]).p[l[1]]=malloc(64);
if((*u[l[0]]).p[l[1]]==NULL){
printf("\n\t(*u[%d]).p[%d]=malloc failed",(l[0]),(l[1]));
continue;
}
((char *)(*u[l[0]]).p[l[1]])[0]='p';
}
}
printf("Why doesn't this print?"); // doesn't print
printf("a thing = %c",(((char *)(*u[3]).p[3])[0])); // doesn't print either
for(l[0]=0;l[0]<uS;l[0]++){
free((*u[l[0]]).p);
for(l[1]=0;l[1]<(*u[l[0]]).pS;l[1]++){
free((*u[l[0]]).p[l[1]]);
}
}
free(u);
}

2. I'm not quite sure what's going on, but here's some things I'd try:

1a) (*pointer).member can be turned into pointer->member.
1b) Use better variable names. l (el) is a horrible choice since it looks so much like a 1 (one).
1c) Use spaces instead of tabs.
2) Get rid of your l (el) array altogether. It's clearer to just create a couple of counter variables such as i and j. It will also eliminate a lot of those square brackets so you can see a little easier what's going on. Which is easier for you to read: u[j]->p or (*u[l[0]]).p)?
3) And finally:
Code:
	for(l[0]=0;l[0]<uS;l[0]++){
free((*u[l[0]]).p);
for(l[1]=0;l[1]<(*u[l[0]]).pS;l[1]++){
free((*u[l[0]]).p[l[1]]);
}
}
This is bad. You're freeing your p pointer and then accessing it right after that. Once you free a pointer you should never touch the memory the pointer used to point to again. Just move your first free() call to after the loop so you free p[whatever] before you free p.

Once you go through those steps the answer will probably jump out and smack you right in the face. If not, post the cleaned up code as you're more likely to get better help once it doesn't look like an IOCCC entry.

3. This line fails:
Code:
#include "windows.h"
#include "stdio.h"
#include "time.h"
#include "math.h"
#include "string.h"

typedef struct UNIT{
void	**p;
int		pS;
}UNIT;

UNIT	**u;
int		uS=10;
int 	L1,L2;

void main(void){
u=malloc(uS*sizeof(UNIT *));
printf("\nu=malloc succeeded");
if(u==NULL){
printf("\n\nu=malloc failed");
return;
}
printf("\nfor(L1){");
for(L1=0;L1<uS;L1++){
printf("\n\tu[%d]->p",L1);
u[L1]->p=malloc(u[L1]->pS*sizeof(void *));
printf(" = malloc");
if(u[L1]->p==NULL){
printf(" \tFAILED");
continue;
}else{
printf(" succeeded");
}
printf("\n\tfor(L2){");
for(L2=0;L2<u[L1]->pS;L2++){
printf("\n\t\tu[%d]->p[%d]",L1,L2);
u[L1]->p[L2]=malloc(64);
printf(" = malloc");
if(u[L1]->p[L2]==NULL){
printf(" \tFAILED");
continue;
}else{
printf(" succeeded");
}
((char *)u[L1]->p[L2])[0]='p';
}
printf("\n\t}");
}
printf("\n}");
printf("\nWhy doesn't this print?");
printf("\na thing = %c",(((char *)u[3]->p[3])[0]));
for(L1=0;L1<uS;L1++){
for(L2=0;L2<u[L1]->pS;L2++){
free(u[L1]->p[L2]);
}
free(u[L1]->p);
}
free(u);
}

4. You're also using void main() instead of int main(), and #include "" instead of #include <>. Adn you're using free() etc without including <stdlib.h>.

Of course that line will fail. You need to allocate u[L1] with something like this:
Code:
u[L1] = malloc(sizeof(UNIT));
and then free it.

5. Originally Posted by dwks
You need to allocate u[L1]
Oops...

Thanks