[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [OT] C programming, variable size array



On Friday 12 December 2003 1:41 pm, Aryan Ameri wrote:
> On Friday 12 December 2003 22:04, Wesley J Landaker wrote:
> > Something like this would work if you fill in some of the blanks:
> >
> > int main() {
> >   int *array = malloc(sizeof(int));
> >   int size = 0;
> >   printf("Enter Number\n");
> >   while (/*not EOF*/) {
> >     size += sizeof(int);
> >     array = realloc(array, size);
> >     scanf("%d", &array[size/sizeof(int)-1]);
> >   }
> > }
>
> About initializing the array as static, well I thought that way, when
> I reinitialize it, I would be able to save it's contents (if you know
> what I mean). I was afraid that if it was a automatic array, when I
> re-initialize it, it's contents would be gone.
>
> Well, apparently I was wrong. Yes, I just studied pointers, but I
> didn't know of malloc and realoc functoins. The man pages are now
> putting me in the right direction.

The trick to understanding here is to know how memory gets allocated. In 
C, there are essentially 3 memory areas you can put things in: the 
static data section, the stack, and the heap. Here is a brief overview 
of the sections:

*** Static Data ***

This is data that is allocated in the actual program image. The storage 
size is determined at compile time, and cannot be resized or 
deallocated during program execution.

Examples of data that goes here are global variables and static 
variables declared inside functions. So for instance, if you write:

char data[1024];

outside of any scope (i.e. not in a function), the compile will hard 
code in 1K of storage for 'data' in the executable image.

'static' variables used in functions get put into this static data 
section, and work essentially like global variables, other than nobody 
else can reference them.

So this code:

int main() {
  static char data[1024];
}

is pretty much the same as:

char data[1024];
int main() {
}

as far as *storage* is concerned. There are, of course, all sorts of 
differences in who can access 'data'.

*** the Stack ***

The stack holds "automatic" variables used in C, and is used by the 
compiler to save data when making function calls and stuff like that.

When you declare a normal variables in a function, it is allocated on 
the stack, and will automatically "disappear". So far instance, if you 
write:

int foo() {
  int x;
  x = 5;
  return 5;
}

int main() {
  int y = foo();
}

And run main, first 'y' will be created on the stack, then foo will get 
called, which will automatically grow the stack to store context 
information, and will create 'x' on the stack. When foo exits, it puts 
the return value on the stack, and then main takes it off the stack and 
puts it in 'y'. The memory used by 'x' is deallocated as the stack 
automatically shrinks. When main exits, the memory used by 'y' is 
deallocated as well.

So:

int main() {
  char data[1024];
}

Will automatically allocate and deallocate 1K of data on the stack. Each 
time main is called, it's a different 1K of data, whereas if it were 
declared static, it would be the *same* 1K of data every time.

You can do cool things, like:

int main() {
  int i;
  for (i=0;i<10;i++) {
    char data[1024];
  }
}

which will allocate a *new* 1K on the stack for every iteration of the 
for loop. After each iteration, the data will be automatically 
deallocated.

Compare this to:

int main() {
  int i;
  for (i=0;i<10;i++) {
    static char data[1024];
  }
}

Despite where we've written the declaration for 'data', it will only be 
allocated once--at compile time--and is essentially the same as:

char data[1024];
int main() {
  int i=0;
  for (i=0;i<10;i++) {
  }
}

*** the Heap ***

The heap is where dynamically allocated memory comes from. In C, you 
have to manage this pretty much manually. That's what malloc() and 
free() do. 

So, to get our 1K of data dynamically at runtime, we'd do:

int main() {
  char *data;
  data = malloc(1024);
  free(data);
}

What happens here is that 'data' is created on the stack; this isn't the 
storage itself, just a pointer. Then we allocated 1K from the heap with 
malloc(), and assign the pointer that returns to data. Now we've got a 
handle on it, and we can use it. When we are done, we must free up the 
memory we allocated with free(), otherwise the memory just stays around 
used up forever until the program finally exits.

> > It would be better to allocate memory in chunks, or better yet, do
> > something like read the numbers into a linked-list and then copy
> > them to an array when you're ready to use them that way, or to use
> > C++ and use the <vector> class, or something like that.

> I should also go and see what is a linked-list :-D

A linked list is basically a set of nodes where each node knows who 
comes after it.

When I was in elementary school, sometimes we'd have to line up for 
something in some specific order. To make sure that every kid always 
got back in line the right way, the teacher made us remember who we 
were after. Each of us kids was a "node"; the line was a linked list.

A node looks like:

struct node {
  int data;
  struct node *next;
};

Notice each node has some data associated with it, and then a pointer to 
another node. To use this as a linked list, you do something like this:

struct node head = malloc(sizeof(node)); // now we have one node
head->next = malloc(sizeof(node)); // now we have two

To do something with the list, you walk down it one node at a time. You 
don't specifically know where all the nodes are (because each one has 
been dynamically allocated), but each node knows where the NEXT node 
is.

Well, that's greatly simplifying things. There is more to it, but that's 
basically how it works.

> And no, it was not a homework. Our instructor wouldn't have given
> this to us, while we haven't learned malloc and realoc yet. It was
> just something that I was curius about.

Well don't be offended if folks are suspicious when you claim it's not 
for homework; the problem was phrased suspiciously like a homework 
assignment, so that's why everybody immediately thinks that you're 
asking about homework.

Anyway, most of us are glad to help you learn and solve problems whether 
it is for homework or not. We just don't want to do your homework for 
you. ;)

Personally, I will happily answer any questions you may have, because I 
think it's a good thing to help people learn how to program well.

> Thanks very much for the tips.

Hope it helps. =)

-- 
Wesley J. Landaker - wjl@icecavern.net
OpenPGP FP: 4135 2A3B 4726 ACC5 9094  0097 F0A9 8A4C 4CD6 E3D2

Attachment: pgpblKktZlHZI.pgp
Description: signature


Reply to: