473,385 Members | 1,780 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,385 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 2327
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: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.