473,231 Members | 2,817 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,231 software developers and data experts.

malloc and pointer hell

I'm trying to learn how to create arrays dynamically. But its just not
happening. Have a look at code below and point and laugh where
appropriate...
First part of program, I'm using an array of pointers, which seems to go
ok. I want to then take it one step further and dynamically create the
array (pointers to pointers). I try to print out the data again,
retrieve the first 3 values (probably by luck), then maybe a pointer
value, and then a seg fault. Doing something wrong, can't see what...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
int * num[5];
int ** digit;
int ** place;
int i;

printf("before assignments\n");
for(i = 0; i < 5; i++)
{
if((num[i] = malloc(sizeof(int) )) == NULL)
{
perror("num malloc\n");
}
*num[i] = i*3;
printf("%d\n",*num[i]);
}

printf("Relooping through the array of pointers\n");
for(i = 0; i < 5; i++)
{
printf("%d\n",*num[i]);
free(num[i]);
}

printf("before pointer to pointer\n");
if((digit = malloc(sizeof(int *) )) == NULL)
{
perror("digit malloc\n");
}
if((place = malloc(sizeof(int **) )) == NULL)
{
perror("place malloc\n");
}
/* hang on to the location of the start of digit */
place = digit;

for(i = 0; i < 5; i++)
{
if((*digit = malloc(sizeof(int) )) == NULL)
{
perror("*digit malloc\n");
}
**digit = i*5;
printf("%d\n",**digit);
*digit++;
}

printf("loop thru digit again\n");

for(i = 0; i < 5; i++)
{
printf("%d\n",**place);
free(*place);
*place++;
}
/*
for(i = 0; i < 5; i++)
{
printf("%d\n",*place[i]);
free(place[i]);
}
*/

free(place);

return(0);
}
Nov 14 '05 #1
7 2320
Fatted wrote:
if((place = malloc(sizeof(int **) )) == NULL)
{
perror("place malloc\n");
}
/* hang on to the location of the start of digit */
place = digit;


That's called "a leak".

/* BEGIN new.c */

#include <stdio.h>
#include <stdlib.h>

#define N_ELEM 5

int main(void)
{
int *num[5];
int **digit;
int **place;
size_t i;

printf("before assignments\n");
for (i = 0; i != N_ELEM; ++i) {
if ((num[i] = malloc(sizeof *num[i])) == NULL) {
perror("num malloc\n");
}
*num[i] = i * 3;
printf("%d\n", *num[i]);
}
printf("Relooping through the array of pointers\n");
for (i = 0; i != N_ELEM; ++i) {
printf("%d\n", *num[i]);
free(num[i]);
}
printf("before pointer to pointer\n");
if ((digit = malloc(N_ELEM * sizeof *digit)) == NULL) {
perror("digit malloc\n");
}
place = digit;
for (i = 0; i != N_ELEM; ++i) {
if((*digit = malloc(sizeof **digit)) == NULL) {
perror("*digit malloc\n");
}
**digit = i * 5;
printf("%d\n", **digit);
++digit;
}
printf("loop thru digit again\n");
digit = place;
for (i = 0; i != N_ELEM; ++i) {
printf("%d\n", **digit);
free(*digit);
++digit;
}
free(place);
return 0;
}

/* END new.c */

--
pete
Nov 14 '05 #2
Fatted <ob******@yahoo.com> wrote in message news:<2r*************@uni-berlin.de>...
I'm trying to learn how to create arrays dynamically. But its just not
happening. Have a look at code below and point and laugh where
appropriate...
First part of program, I'm using an array of pointers, which seems to go
ok. I want to then take it one step further and dynamically create the
array (pointers to pointers). I try to print out the data again,
retrieve the first 3 values (probably by luck), then maybe a pointer
value, and then a seg fault. Doing something wrong, can't see what...
<snip> int * num[5];
int ** digit;
int ** place;
int i; <snip> printf("loop thru digit again\n");
for(i = 0; i < 5; i++)
{
printf("%d\n",**place);
free(*place);
*place++;
}

<snip>

your code isn't very clear, your question isn't either.. are you
trying to dynamically create one dimensional arrays or two dimensional
arrays, or something else?
Nov 14 '05 #3


Fatted wrote:
I'm trying to learn how to create arrays dynamically. But its just not
happening. Have a look at code below and point and laugh where
appropriate...
First part of program, I'm using an array of pointers, which seems to go
ok. I want to then take it one step further and dynamically create the
array (pointers to pointers). I try to print out the data again,
retrieve the first 3 values (probably by luck), then maybe a pointer
value, and then a seg fault. Doing something wrong, can't see what...

Yes your "digit" allocations took to be wrong.
num is an array of 5 int pointers. You have that correct.
However, with digit, it seems to me that you want to allocate
a 2d array.

See the corrections below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
int * num[5];
int ** digit;
int ** place;
int i;

.........snip........

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int *num[5];
int *narray;
int ** digit;
int *tmp;
int i,j;

for(i = 0; i < 5; i++)
{
if((num[i] = malloc(sizeof(int) )) == NULL)
{
perror("num malloc\n");
exit(EXIT_FAILURE);
}
*num[i] = i*3;
printf("*num[%d] = %d\n",i , *num[i]);
}
puts("Freeing num");
for(i = 0; i < 5; i++)
free(num[i]);
puts("\nAllocating an array of ints");
if((narray = malloc((sizeof *narray)*5)) == NULL)
{
perror("narray allocation failure");
exit(EXIT_FAILURE);
}
for(i = 0; i < 5; i++)
{
narray[i] = i*3;
printf("narray[%d] = %d\n",i,narray[i]);
}
puts("Freed narray with free(narray)");
free(narray);
puts("\nPress enter to continue");
getchar();
puts("\n2d allocations. First row= 5 and col = 1");
if((digit = malloc((sizeof *digit)*5)) == NULL)
{
perror("digit allocation error");
exit(EXIT_FAILURE);
}
for(i = 0; i < 5; i++)
if((digit[i] = malloc(sizeof *digit[i])) == NULL)
{
for(--i;i >= 0; --i) free(digit[i]);
free(digit);
exit(EXIT_FAILURE);
}
for(i = 0; i < 5; i++)
{
digit[i][0] = i*3;
printf("digit[%d][0] = %d\n",i,digit[i][0]);
}
puts("\nEnlarging the 2d array to row = 5 and col = 2\n"
" (preserving the original array)");
for(i = 0;i < 5;i++)
{
tmp = realloc(digit[i],(sizeof *digit[i])*2);
if(tmp == NULL)
{
perror("Failure in enlarging 2d");
for(i = 0; i < 5;i++) free(digit[i]);
free(digit);
exit(EXIT_FAILURE);
}
digit[i] = tmp;
}
for(i = 0; i < 5;i++) digit[i][1] = i*6;
for(i = 0; i < 5;i++)
for(j = 0;j < 2;j++)
printf("digit[%d][%d] = %d\n",i,j,digit[i][j]);
puts("Freeing the 2d array");
for(i = 0;i < 5; i++) free(digit[i]);
free(digit);
return 0;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #4
Fatted <ob******@yahoo.com> wrote in message news:<2r*************@uni-berlin.de>...
I'm trying to learn how to create arrays dynamically. But its just not
happening. Have a look at code below and point and laugh where
appropriate...
First part of program, I'm using an array of pointers, which seems to go
ok. I want to then take it one step further and dynamically create the
array (pointers to pointers). I try to print out the data again,
retrieve the first 3 values (probably by luck), then maybe a pointer
value, and then a seg fault. Doing something wrong, can't see what...


Here's the general way to create 2-d arrays on the fly:

#include <stdlib.h>

#define ROWS 5
#define COLS 7

int main (void)
{
int **arr; /* arr will be a 5x7 array of int */
int i, j;

arr = malloc (sizeof *arr * ROWS); /* type of *arr == int * */
if (!arr)
{
/* handle error */
}
else
{
for (i = 0; i < ROWS; i++)
{
arr[i] = malloc (sizeof *arr[i] * COLS); /* type of
*arr[i] == int */
if (!arr[i])
{
/* handle error */
}
else
{
for (j = 0; j < COLS; j++)
{
arr[i][j] = /* whatever initial value you prefer
*/
}
}
}
}

return 0;
}

I didn't mark up your program because I frankly don't understand what
you were trying to do, and don't have enough time to seriously study
it.
Nov 14 '05 #5
Fatted wrote:
I'm trying to learn how to create arrays dynamically.


See the FAQ, question 6.16. I think this is what you're after.

http://www.eskimo.com/~scs/C-faq/q6.16.html

--
Derrick Coetzee
Nov 14 '05 #6
On Tue, 21 Sep 2004 12:17:53 +0200, Fatted <ob******@yahoo.com> wrote:
I'm trying to learn how to create arrays dynamically. But its just not
happening. Have a look at code below and point and laugh where
appropriate...
First part of program, I'm using an array of pointers, which seems to go
ok. I want to then take it one step further and dynamically create the
array (pointers to pointers). I try to print out the data again,
retrieve the first 3 values (probably by luck), then maybe a pointer
value, and then a seg fault. Doing something wrong, can't see what...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
int * num[5];
int ** digit;
int ** place;
int i;

printf("before assignments\n");
for(i = 0; i < 5; i++)
{
if((num[i] = malloc(sizeof(int) )) == NULL)
{
perror("num malloc\n");
}
*num[i] = i*3;
printf("%d\n",*num[i]);
}

printf("Relooping through the array of pointers\n");
for(i = 0; i < 5; i++)
{
printf("%d\n",*num[i]);
free(num[i]);
}

printf("before pointer to pointer\n");
if((digit = malloc(sizeof(int *) )) == NULL)
This allocates space for only one pointer.
{
perror("digit malloc\n");
}
if((place = malloc(sizeof(int **) )) == NULL)
This allocates the wrong amount of space. place is an int**. The
thing it points to must be an int*. If sizeof(int*) < sizeof(int**),
you will not have enough room to initialize *place.
{
perror("place malloc\n");
}
/* hang on to the location of the start of digit */
place = digit;
As others have noted, you no longer have access to the memory that was
allocated for place. Consequently you cannot free it.

for(i = 0; i < 5; i++)
{
if((*digit = malloc(sizeof(int) )) == NULL)
The first time through the loop, this stores the address of some
allocated memory in the int* pointed to by digit. You never free this
memory.

On subsequent iterations of the loop, that same int* is set to new
addresses. The memory allocated at the old addresses is never freed.
Once *digit is set to a new value, you have no way of accessing the
old memory or freeing it.
{
perror("*digit malloc\n");
}
**digit = i*5;
printf("%d\n",**digit);
*digit++;
This causes the int* that digit points to to point to the byte
immediately after the int value i*5 that was stored there. Unless and
until you do a *digit-- or equivalent, you cannot dereference *digit
since it points to memory you don't own.
}

printf("loop thru digit again\n");

for(i = 0; i < 5; i++)
{
printf("%d\n",**place);
place points to the int* that was allocated for digit. That int* was
incremented to point to memory you don't own. **place is a
dereference of *digit that I mentioned above and invokes undefined
behavior.
free(*place);
*place does not evaluate to the address of an area allocated by
malloc. This also invokes undefined behavior.
*place++;
If the above free had worked, *place would be indeterminate and this
attempt to evaluate it would also result in undefined behavior.
}
/*
for(i = 0; i < 5; i++)
{
printf("%d\n",*place[i]);
free(place[i]);
}
I'm sorry but you got yourself completely lost here. Under the best
of circumstances, *place[i] only exists when i is 0.
*/

free(place);

return(0);
}


<<Remove the del for email>>
Nov 14 '05 #7
Groovy hepcat Barry Schwarz was jivin' on 22 Sep 2004 05:19:29 GMT in
comp.lang.c.
Re: malloc and pointer hell's a cool scene! Dig it!
On Tue, 21 Sep 2004 12:17:53 +0200, Fatted <ob******@yahoo.com> wrote:
I'm trying to learn how to create arrays dynamically. But its just not
happening. Have a look at code below and point and laugh where
appropriate...
First part of program, I'm using an array of pointers, which seems to go
ok. I want to then take it one step further and dynamically create the
array (pointers to pointers). I try to print out the data again,
retrieve the first 3 values (probably by luck), then maybe a pointer
value, and then a seg fault. Doing something wrong, can't see what...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
int * num[5];
int ** digit;
int ** place;
int i;

printf("before assignments\n");
for(i = 0; i < 5; i++)
{
if((num[i] = malloc(sizeof(int) )) == NULL)
{
perror("num malloc\n");
}
*num[i] = i*3;
printf("%d\n",*num[i]);
}

printf("Relooping through the array of pointers\n");
for(i = 0; i < 5; i++)
{
printf("%d\n",*num[i]);
free(num[i]);
}

printf("before pointer to pointer\n");
if((digit = malloc(sizeof(int *) )) == NULL)
This allocates space for only one pointer.
{
perror("digit malloc\n");
}
if((place = malloc(sizeof(int **) )) == NULL)


This allocates the wrong amount of space. place is an int**. The
thing it points to must be an int*. If sizeof(int*) < sizeof(int**),
you will not have enough room to initialize *place.
{
perror("place malloc\n");
}
/* hang on to the location of the start of digit */
place = digit;


As others have noted, you no longer have access to the memory that was
allocated for place. Consequently you cannot free it.

for(i = 0; i < 5; i++)
{
if((*digit = malloc(sizeof(int) )) == NULL)


The first time through the loop, this stores the address of some
allocated memory in the int* pointed to by digit. You never free this
memory.

On subsequent iterations of the loop, that same int* is set to new
addresses. The memory allocated at the old addresses is never freed.


Wrong. The value of digit is modified in the loop.
Once *digit is set to a new value, you have no way of accessing the
old memory or freeing it.
{
perror("*digit malloc\n");
}
**digit = i*5;
printf("%d\n",**digit);
*digit++;
This causes the int* that digit points to to point to the byte
immediately after the int value i*5 that was stored there. Unless and


No it doesn't. It causes digit to be modified, and also dereferences
the value of digit before the modification, discarding the result. It
does not modify *digit.
until you do a *digit-- or equivalent, you cannot dereference *digit
since it points to memory you don't own.
Actually, it is the value of digit itself that is now invalid.
Dereferencing digit is a no-no.
}

printf("loop thru digit again\n");

for(i = 0; i < 5; i++)
{
printf("%d\n",**place);


place points to the int* that was allocated for digit. That int* was
incremented to point to memory you don't own. **place is a


No it wasn't.
dereference of *digit that I mentioned above and invokes undefined
behavior.


Nonsense.
free(*place);


*place does not evaluate to the address of an area allocated by
malloc. This also invokes undefined behavior.


Yes it does.
*place++;


If the above free had worked, *place would be indeterminate and this
attempt to evaluate it would also result in undefined behavior.


That's right. place is dereferenced, the resulting value is
discarded, and place is incremented. This will result in disaster when
attempting to free the memory at which place used to point.
}
/*
for(i = 0; i < 5; i++)
{
printf("%d\n",*place[i]);
free(place[i]);
}


I'm sorry but you got yourself completely lost here. Under the best
of circumstances, *place[i] only exists when i is 0.


True.
*/

free(place);
And here we have undefined behaviour. See above.
return(0);
Fatted, return is not a function. The parentheses around the return
value are superfluous. It's not an error, just unnecessary.
}


--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
Nov 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
by: john smith | last post by:
Can someone please explain to me what is happening when I do a malloc(0). This is what I did. int* p = (int*)malloc(0); Then I printed the value of p and of course it was non-null. But...
66
by: Knady | last post by:
Hi, I have the following problem, I must to do my assignment, but I really do not know how to use the malloc. I need create a program that will be used to do some algebrical computation on the...
33
by: hermit_crab67 | last post by:
Can someone explain to a C newbie why this doesn't work as I expect it to work? (expectations clearly outlined in the printf statement in main routine) OS: Linux 2.4.26 GCC: 2.95.4 void...
7
by: Rano | last post by:
/* Hello, I've got some troubles with a stupid program... In fact, I just start with the C language and sometime I don't understand how I really have to use malloc. I've readden the FAQ...
68
by: James Dow Allen | last post by:
The gcc compiler treats malloc() specially! I have no particular question, but it might be fun to hear from anyone who knows about gcc's special behavior. Some may find this post interesting;...
9
by: Me | last post by:
Hi, I ran into a malloc problem but I can't find the solution. I try to read a file into a variable with malloc like this: BYTE *lcdata; lcdata = malloc(fsize*sizeof(BYTE));
82
by: quiberon2 | last post by:
Hi, Sorry if it might be a stupid question but what should returns malloc(0) ? void *ptr = malloc(0); I am running gcc 3.3.5 and a non-null address is returned. ( in the compiler that I am...
25
by: Why Tea | last post by:
Thanks to those who have answered my original question. I thought I understood the answer and set out to write some code to prove my understanding. The code was written without any error checking....
25
by: jbholman | last post by:
I am pretty new to C and doing my first project in C. I actually read almost the entire FAQ, but can't seem to figure out this problem. I have a structure. I have a list of these structures. ...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.