Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: (newbie) question concerning memory allocation

Reply
Thread Tools

Re: (newbie) question concerning memory allocation

 
 
Ben Bacarisse
Guest
Posts: n/a
 
      09-29-2012
lipska the kat <> writes:

> Ubuntu Linux 12.04 LTS 64bit
> gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
> /bin/bash
>
> Hi
>
> I'm a raw beginner at C so please excuse me if
> the answer to my question is obvious.
>
> I have the following program called
> pointers.c It compiles and if I run it
> thusly:
>
> $pointers 3
>
> I get the expected output
>
> 1 2 3


As you've now found out, correct output is no indicator that a program
is correct. It's a very good idea to start thinking about programs by
making logical inferences from the source. You don't need a formal
systems for this; you can go a long way with some very informal rules.

> #include <stdio.h>
> #include <stdlib.h>
>
> int main(int argc, char *argv[]){
>
> struct foo{
> int bar;
> long baz;
> };
>
> int x = 0;
>
> if(argc > 1){
> x = atoi(argv[1]);
> }


(aside: for test programs like this I tend to write

int x = argc > 1 ? atoi(argv[1]) : 0;

because it's so short and it keeps the default value (0) close.)

> struct foo **foos;
> struct foo **bars;
>
> int i;


You are mixing declarations and statements. This is permitted in modern
C, but I would then go further and put the declaration of i into the for
statement itself:

for (int i = 0; i < x; i++) ...

> /* create foos*/
> for(i = 0; i < x; i++){
> *foos = malloc(sizeof(struct foo));


Form what you write below, you know what's wrong here, yes?

I like to use this pattern for malloc calls: p = malloc(n * sizeof *p);
so that there is no need to check the you are using the right type in
the sizeof expression. When the number is obviously 1, I omit it.:

*foos = malloc(sizeof **foos);

> (*foos)->bar = i + 1;
> (*foos)->baz = i + 2;
> ++foos;
> }
>
> /* set foos back to the first foo */
> foos-=x;


Changing foos gives you more work to do. I'd write it like this:

for (int i = 0; i < x; i++) {
foos[i] = malloc(sizeof *foos[i]);
foos[i]->bar = i + 1;
foos[i]->baz = i + 2;
}

> /* print foos */
> for(i = 0; i < x; i++){
> printf("%d ", foos[i]->bar);
> }
>
> printf("\n");
>
> return 0;
> }
>
> This is all well and good, however if I use gdb with a suitable break
> to look at the values for foos and bars
> I get the following
>
> (gdb) print/x foos
> $1 = 0x7fffffffe1f0
> (gdb) print/x bars
> $2 = <optimized out>
>
> fair enough, I'm not using bars
>
> If I change the code so that it reads
>
> struct foo **foos;
> struct foo **bars;
> bars = foos;
>
> I get a seg fault when I run the program
>
> If I put a break just before the assignment
>
> bars = foos;
>
> and print the values of foos and bars
> I get the following
>
> (gdb) print/x foos
> $1 = 0x4004f0
> (gdb) print/x bars
> $2 = 0x7fffffffe1f0
>
> now when I assign the value in foos to bars
> and run the program it seg faults at the line
>
> *foos = malloc(sizeof(struct foo));
>
> I think I understand why the segfault occurs
> it's because I'm trying to access unavailable memory
>
> The question is, why does declaring a second pointer to the array of
> pointers


They are not pointers to arrays, despite what people say. They are
pointers to pointers. A pointer to an array can be declared (and can be
very useful) but it looks quote different). A good way to talk about
such a thing is as a pointer to the first element of an array.

> to foo cause the first pointer (foos) be be allocated an
> unavailable memory slot.


Altering the source code will likely alter what code gcc generates, but
when a program does something as unpredictable as accessing memory
through an uninitialised pointer it seems pointless to try to dig out
exactly why it behaves differently.

If gcc can no longer removes the other pointer, where foos lies in
memory may well change and what "happens to be there" is likely to be
different. This is a guess, but I don't think finding out is likely to
be very interesting or useful.

Bu the way, I can't recommend valgrind enough, especially while
learning. Don't do anything else before installing it! Compile with -g
and "valgrind ./program 3" says:

==14141== Use of uninitialised value of size 8
==14141== at 0x400620: main (x.c:24)

and so on. I never leave home without it (home == emacs of course).

--
Ben.
 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      09-29-2012
lipska the kat <> writes:

> On 29/09/12 14:11, Ben Bacarisse wrote:
>> lipska the kat<> writes:
>>

> [snip]
>
>>> The question is, why does declaring a second pointer to the array of
>>> pointers

>>
>> They are not pointers to arrays, despite what people say. They are
>> pointers to pointers. A pointer to an array can be declared (and can be
>> very useful) but it looks quote different). A good way to talk about
>> such a thing is as a pointer to the first element of an array.

>
> I'm just trying to get my head around this whole pointers to arrays
> thing, If I manage to create a data structure rooted at **foos
> I can access the instances using array indexing despite the fact that
> no array initialization code darkens my doorstep. I'm just accepting
> this at the moment and hoping the subconscious processor in my head
> will do the rest.


A pointer to an array looks like this:

int (*ap)[10];

and you could set ap like this:

int ar[10];
ap = &ar;

but it is very common to say that after

int *ip = ar;

ip "points to the array" ar. Most of the time it doesn't matter,
but ip really just points to one element of the array (the first).

Have you seen the C faq? In particular 6.13:
http://c-faq.com/aryptr/ptrtoarray.html

<snip>
--
Ben.
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      09-29-2012
Ben Bacarisse <> writes:
[...]
> Have you seen the C faq? In particular 6.13:
> http://c-faq.com/aryptr/ptrtoarray.html


I recommend reading all of section 6. The relationship between arrays
and pointers in C can be very confusion; that FAQ section explains it
better than anything else I've seen. The whole FAQ is an excellent
resource.

--
Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Anand Hariharan
Guest
Posts: n/a
 
      10-10-2012
On Sep 29, 8:11*am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> lipska the kat <lipskathe...@yahoo.co.uk> writes:

(...)
> > * */* create foos*/
> > * *for(i = 0; i < x; i++){
> > * * * * * **foos = malloc(sizeof(struct foo));

>
> Form what you write below, you know what's wrong here, yes?
>


Considering that the OP had difficulties with the dereferencing
syntax, in addition to what you say below ...


> I like to use this pattern for malloc calls: p = malloc(n * sizeof *p);
> so that there is no need to check the you are using the right type in
> the sizeof expression. *When the number is obviously 1, I omit it.:
>
> * *foos = malloc(sizeof **foos);
>


.... I would elaborate that the sizeof expression is evaluated at
compile time and there isn't any dereferencing involved.

Writing malloc like above is idiomatic usage and good from a software
engineering perspective; but I find that it is quite difficult to
explain it to someone learning C. YMMV.

- Anand

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: (newbie) question concerning memory allocation Eric Sosman C Programming 6 10-10-2012 08:38 PM
Re: (newbie) question concerning memory allocation Joe Pfeiffer C Programming 0 09-29-2012 09:48 PM
An idea for heap allocation at near stack allocation speed Bjarke Hammersholt Roune C++ 14 03-06-2011 08:07 AM
static memory allocation versus dynamic memory allocation Ken C Programming 24 11-30-2006 12:37 AM
What is the difference between dynamic memory allocation,and stack allocation ? chris C++ 6 10-28-2005 05:27 AM



Advertisments