1

I wrote up this c program to get a feel for structure and pointers.

The problem

The program works fine atleast when it comes to taking in the input(confirmed by testing it via gdb) , what isn't right is that when it comes to printing the output data, it seems to be overwritten by something...

The Question

If the compiler reserves memory for a certain array , is it right to assume that after the "death" of a function , the reservation ends, and the memory is given to some other process,? and hence that wiould explain why the struct data is being over written?

The code

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

    typedef struct {int marks;int roll;} ADDRESS ;

    void printer(ADDRESS* pointer,int len)
         {          printf("-- Entering printing mode -- \n");
                ADDRESS* p1;
                p1=pointer;
                int counter=0;
                while ( counter < len)
                {
                   printf(" --> Entry %d  \n",counter);
                   printf("Marks : %d \n",p1->marks);
                   printf("Roll : %d \n ",p1->roll);
                   counter++;p1++;
                }
         }

     ADDRESS *stater(int number)
           {    
                   printf("\t STANDBY FOR INPUT PART \t \n\n\n");
               ADDRESS x[number];
               ADDRESS *c,*i;
               c=x;
               i=c;
               int counterf=number;
               int counter=0;
               while (counter!=counterf)
                   {
                        printf("\t Input the mark : ");
                        scanf("%d",&(c->marks));
                        printf("\t Input the roll : ");
                        scanf("%d",&(c->roll));
                        printf("\n");
                        counter++;
                        c=c+1;
                   }
               return i;
              }



            int main()
                 {
                         ADDRESS *o=stater(4);
                         printer(o,4);
                         return 0;

                  }
metric-space
  • 541
  • 4
  • 14

2 Answers2

3

After the memory is freed it will often be reassigned. This is especially true when that memory is stored on the stack. So, yes.

J.Miller
  • 477
  • 1
  • 3
  • 14
  • Cool.So is there a way to extend the scope of the data initialized in the function? – metric-space Apr 10 '13 at 22:37
  • 2
    If you mean you want to preserve memory beyond a function scope you can allocate it on the heap using [`malloc()`](http://www.cplusplus.com/reference/cstdlib/malloc/) – Kninnug Apr 10 '13 at 22:40
  • Aha nice nice , and now I understand why people keep using malloc() all over the place.Cool indeed. – metric-space Apr 10 '13 at 22:41
  • 1
    `malloc()` returns a pointer to the heap. The pointer will point to a block whose size is minimum the size you requested or it will return NULL if malloc fails. A pointer recieved from malloc must be free'd explicitly (i.e. calling `free(pointer)` when you are done using it). If you do not free the pointer you get a memory leek, which is bad. Also if you use a pointer to the heap after you have free'd it bad things can happen (like overwriting data). – J.Miller Apr 10 '13 at 22:49
  • as said Kninnug, malloc should do what you want. If you allocate your array with "ADDRESS x[number]" (static allocation) it will be released outside it's block {}. If you use malloc (dynamic allocation), it will be release with free(). You have also to be aware about differences between dynamic and static allocation, please check these links: http://stackoverflow.com/questions/8385322/defference-between-static-memory-allocation-and-dynamic-memory-allocation and http://wiki.answers.com/Q/Difference_between_dynamic_and_static_memory_allocation_in_C – hzrari Apr 10 '13 at 22:55
  • @Linuxows Are you sure about the malloc thing? replacing the array with this ADDRESS *t =malloc(number*sizeof(ADDRESS)) , isn't doing it, or is it just me? – metric-space Apr 10 '13 at 22:55
  • The right usage of malloc is with casting elements: ADDRESS *t =(ADDRESS*)malloc(number*sizeof(ADDRESS)) – hzrari Apr 10 '13 at 22:57
  • @Linuxows just want to let you know, the compiler wasn't complaining before I put in ADDRESS t =(ADDRESS)malloc(number*sizeof(ADDRESS)) ..and now it is ...hmm ..any clue as to why it is doing so? the error is "feel.c: In function ‘stater’: feel.c:22:2: error: conversion to non-scalar type requested ADDRESS x=(ADDRESS)malloc(number*sizeof(ADDRESS)); ^ feel.c:24:3: error: incompatible types when assigning to type ‘struct ADDRESS *’ from type ‘ADDRESS’ c=x; " – metric-space Apr 10 '13 at 23:06
  • you need to add * after the cast (ADDRESS), it was mis-displayed in my last comment, i don't know why. I wrote the whole code in the answer below. Please refer to it – hzrari Apr 10 '13 at 23:08
1

This worked properly for me:

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

typedef struct {int marks;int roll;} ADDRESS ;

void printer(ADDRESS* pointer,int len)
     {          printf("-- Entering printing mode -- \n");
            ADDRESS* p1;
            p1=pointer;
            int counter=0;
            while ( counter < len)
            {
               printf(" --> Entry %d  \n",counter);
               printf("Marks : %d \n",p1->marks);
               printf("Roll : %d \n ",p1->roll);
               counter++;p1++;
            }
     }

ADDRESS *stater(int number)
       {    
           printf("\t STANDBY FOR INPUT PART \t \n\n\n");
           ADDRESS* x = (ADDRESS *)malloc(number*sizeof(ADDRESS));
           ADDRESS *c,*i;
           c=x;
           i=c;
           int counterf=number;
           int counter=0;
           while (counter!=counterf)
               {
                    printf("\t Input the mark : ");
                    scanf("%d",&(c->marks));
                    printf("\t Input the roll : ");
                    scanf("%d",&(c->roll));
                    printf("\n");
                    counter++;
                    c=c+1;
               }
           return i;
          }



        int main()
             {
                     ADDRESS *o=stater(4);
                     printer(o,4);
                     return 0;

              }
hzrari
  • 1,803
  • 1
  • 15
  • 26
  • Yep yep my sincerest apologies.Turns out I kept compiling the file with -g flag..and blah blah did not really use a modified executable.Your version , but so does the " ADDRESS *t =malloc(number*size(ADDRESS)).I now wonder if the casting is really necessary? – metric-space Apr 10 '13 at 23:13
  • 1
    I used to do it like that. It depends on your usage, it depends on your compiler option, optimization, platform target and flags. There a lot of debates about to cast the malloc or not. Personally, I prefer cast, I used to work on embedded platforms on which pointers doesn't have the same memory size than integers. So the behavior can be not the expected... – hzrari Apr 10 '13 at 23:20