Dinamic Array Allocation problems

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • stararic
    New Member
    • Jun 2009
    • 14

    #16
    ok... now I use 2 functions for the allocation of memori:

    Code:
    void resize(int *array, int *d, int dim)
    {	if(dim>MAXDIM){printf("raggiunta dim max"); exit(2);}
    
    		array=realloc(array,(dim)*sizeof(int));
    		if(array==NULL) {printf("errore: impossibile allocare altra memoria"); exit(2);}
    		if(d==NULL){printf("errore: '*' su puntatore a NULL"); exit(2);}
    		*d=dim;
    
    }
    
    elemento inizializza (int dim)
    {int i;elemento a;
    	if(dim>MAXDIM){printf("raggiunta dim max"); exit(2);}
    	a.array=malloc(dim*sizeof(int));
    	if(a.array==NULL) {printf("errore: impossibile allocare altra memoria"); exit(2);}
    	a.array[0]=1;
    	for(i=1;i<dim;i++)a.array[i]=0;
    	a.d=dim;
    	a.succ=NULL;
    	a.n=1;
    	return a;
    }
    And remember the type elemento:
    Code:
    typedef struct el {int *array; int n; int d; struct el *succ;} elemento;
    when I use this in the function:
    Code:
    elemento DecToBin(elemento a)
    {elemento decimale,tmp1,resto, binario,zero;
    int i,j,tmp;
    
    zero=inizializza(2);
    zero.array[1]=0;
    zero.n++;
    
    decimale=inizializza(a.d);
    decimale.n=a.n;
    binario=inizializza(2);
    resto=inizializza(2);	
    tmp1=decimale;
    
    for(i=0;i<decimale.n;i++) decimale.array[i]=a.array[i];
    while(maggiore(decimale,zero)==0)
    {decimale=DivSemplice(tmp1,1,2);
    	binario.array[binario.n]=tmp1.array[tmp1.n-1]%2;
    	tmp1=decimale;		
    	decimale=tmp1;
    	binario.n++;
    	if(binario.n==binario.d) resize(binario.array,&(binario.d), 2*binario.n);
    	
    }
    
    for(i=1, j=binario.n-1;i<j;i++,j--)  {tmp=binario.array[j];binario.array[j]=binario.array[i];binario.array[i]=tmp;}
    if(decimale.array[0]==1)binario.array[0]=1;
    else binario.array[0]=-1;
    I get:

    *** glibc detected *** /home/richard/progettino/calc: realloc(): invalid next size: 0x088c90e0 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6[0xb7f46604]
    /lib/tls/i686/cmov/libc.so.6[0xb7f4a1b1]
    /lib/tls/i686/cmov/libc.so.6(reall oc+0x106)[0xb7f4aee6]
    /home/richard/progettino/calc[0x8048c2f]
    /home/richard/progettino/calc[0x804b8b5]
    /home/richard/progettino/calc[0x8048831]
    /lib/tls/i686/cmov/libc.so.6(__lib c_start_main+0x e5)[0xb7eed775]
    /home/richard/progettino/calc[0x80484a1]
    ======= Memory map: ========
    08048000-0804d000 r-xp 00000000 08:01 5105080 /home/richard/progettino/calc
    0804d000-0804e000 r--p 00004000 08:01 5105080 /home/richard/progettino/calc
    0804e000-0804f000 rw-p 00005000 08:01 5105080 /home/richard/progettino/calc
    088c9000-088ea000 rw-p 088c9000 00:00 0 [heap]
    b7d00000-b7d21000 rw-p b7d00000 00:00 0
    b7d21000-b7e00000 ---p b7d21000 00:00 0
    b7ed6000-b7ed7000 rw-p b7ed6000 00:00 0
    b7ed7000-b8033000 r-xp 00000000 08:01 2786520 /lib/tls/i686/cmov/libc-2.9.so
    b8033000-b8034000 ---p 0015c000 08:01 2786520 /lib/tls/i686/cmov/libc-2.9.so
    b8034000-b8036000 r--p 0015c000 08:01 2786520 /lib/tls/i686/cmov/libc-2.9.so
    b8036000-b8037000 rw-p 0015e000 08:01 2786520 /lib/tls/i686/cmov/libc-2.9.so
    b8037000-b803a000 rw-p b8037000 00:00 0
    b803c000-b8049000 r-xp 00000000 08:01 2768961 /lib/libgcc_s.so.1
    b8049000-b804a000 r--p 0000c000 08:01 2768961 /lib/libgcc_s.so.1
    b804a000-b804b000 rw-p 0000d000 08:01 2768961 /lib/libgcc_s.so.1
    b804b000-b804f000 rw-p b804b000 00:00 0
    b804f000-b8050000 r-xp b804f000 00:00 0 [vdso]
    b8050000-b806c000 r-xp 00000000 08:01 2768919 /lib/ld-2.9.so
    b806c000-b806d000 r--p 0001b000 08:01 2768919 /lib/ld-2.9.so
    b806d000-b806e000 rw-p 0001c000 08:01 2768919 /lib/ld-2.9.so
    bfd58000-bfd6d000 rw-p bffeb000 00:00 0 [stack]

    Program received signal SIGABRT, Aborted.
    0xb804f430 in __kernel_vsysca ll ()

    the program is compiled with gcc -Wall --pedantic and for the run time I used gdb... Please save me:(

    Comment

    • donbock
      Recognized Expert Top Contributor
      • Mar 2008
      • 2427

      #17
      Regarding your function resize, the realloc function may not be able to extend the specified memory block. In that case, it allocates a new block with the larger size, copies the contents of the original block into the new block, and frees the original block. Therefore, you need to be able to accommodate the value of the 'array' pointer changing after you call resize. That is, the pointer value returned by realloc needs to be written into the array field of the relevant elemento.

      You should check if realloc is used anywhere else.

      Comment

      • stararic
        New Member
        • Jun 2009
        • 14

        #18
        there is not other function who use realloc...

        Comment

        • stararic
          New Member
          • Jun 2009
          • 14

          #19
          I've not undestand what is the problem...

          Comment

          • donbock
            Recognized Expert Top Contributor
            • Mar 2008
            • 2427

            #20
            Originally posted by stararic
            I've not undestand what is the problem...
            Have you changed how function resize is used in accordance with my advice in Message #17? Did that have any effect?

            Comment

            • stararic
              New Member
              • Jun 2009
              • 14

              #21
              how can i do it? something like:
              Code:
              void resize(int *array, int *d, int dim)
              {int *tmp;int i;
              		if(array==NULL){printf("array null in resize"); exit(2);}
              		if(dim>MAXDIM){printf("raggiunta dim max"); exit(2);}
              		tmp=malloc((dim)*sizeof(int));
              		if(array==NULL) {printf("errore: impossibile allocare altra memoria"); exit(2);}
              		for(i=0;i<=*d;i++) tmp[i]=array[i]; for(;i<=dim;i++) tmp[i]=0;
              		free(array);
              		array=tmp;}
              		if(d==NULL){printf("errore: '*' su puntatore a NULL"); exit(2);}
              		*d=dim;
              
              }
              doesn't work at all...
              *** glibc detected *** ./calc: free(): invalid next size (fast): 0x0970c030 ***

              realloc returns NULL if it cannot extend the array's block? if yes, I can do something like


              Code:
               
              void resize(int *array, int *d, int dim)
               {int i, *tmp;  
                if(dim>MAXDIM){printf("raggiunta dim max"); exit(2);}
                       array=realloc(array,(dim)*sizeof(int));
                       if(array==NULL) {
                              tmp=malloc((dim)*sizeof(int));
              		if(array==NULL) {printf("errore: impossibile allocare altra memoria"); exit(2);}
              		for(i=0;i<=*d;i++) tmp[i]=array[i]; for(;i<=dim;i++) tmp[i]=0;
              		free(array);
              		array=tmp;}
                     if(d==NULL){printf("errore: '*' su puntatore a NULL"); exit(2);}
                     *d=dim;
              }

              Is this what you means in msg 17?

              Comment

              • donbock
                Recognized Expert Top Contributor
                • Mar 2008
                • 2427

                #22
                1. Change resize to return a pointer to the resized array.
                2. Change each resize caller so that they copy that returned pointer into the relevant elemento array field. There is no necessity for the resize callers to compare the returned pointer to NULL since resize does that for you; but there is also no harm in it either.

                Or change resize so that you pass it two parameters: a pointer to an elemento and the desired new size. Resize could then update the array and dim fields of the elemento itself.

                Comment

                • stararic
                  New Member
                  • Jun 2009
                  • 14

                  #23
                  But when I use resize, if a is an element I do:
                  resize(a.array, &(a.d), dim);
                  so when in resize i do array=realloc(a rray,dim)); it is supposed to change the value of "array" to the pointer at the new block, and "array" is the array field of elemento... So I think I've done what you suggenst when I call resize... Is it wrong?Doesn't work with a void function?

                  Comment

                  • stararic
                    New Member
                    • Jun 2009
                    • 14

                    #24
                    ohhhhhh my god it seems working! no resize error with the code:

                    Code:
                     int *resize(int *array, int *d, int dim)
                      {int i, *tmp;  
                       if(dim>MAXDIM){printf("raggiunta dim max"); exit(2);}
                              array=realloc(array,(dim)*sizeof(int));
                              if(array==NULL) {
                                     tmp=malloc((dim)*sizeof(int));
                            if(array==NULL) {printf("errore: impossibile allocare altra memoria"); exit(2);}
                             for(i=0;i<=*d;i++) tmp[i]=array[i]; for(;i<=dim;i++) tmp[i]=0;
                             free(array);
                             array=tmp;}
                            if(d==NULL){printf("errore: '*' su puntatore a NULL"); exit(2);}
                            *d=dim;
                    return array;
                     }
                    but really I don't understand why... Now there is just some double free error, above all after some iterations of the code. maybe there is some wrong free... I will check for it. thanks a lot

                    Comment

                    • donbock
                      Recognized Expert Top Contributor
                      • Mar 2008
                      • 2427

                      #25
                      Originally posted by stararic
                      Code:
                      int *resize(int *array, int *d, int dim)
                         {
                         int i, *tmp;  
                         if(dim>MAXDIM) {
                            printf("raggiunta dim max"); 
                            exit(2);
                            }
                         array=realloc(array,(dim)*sizeof(int));
                         if(array==NULL) {
                            tmp=malloc((dim)*sizeof(int));
                            if(array==NULL) {
                               printf("errore: impossibile allocare altra memoria"); 
                               exit(2);
                               }
                            for(i=0;i<=*d;i++) 
                               tmp[i]=array[i]; 
                            for(;i<=dim;i++) 
                               tmp[i]=0;
                            free(array);
                            array=tmp;
                            }
                         if(d==NULL) {
                            printf("errore: '*' su puntatore a NULL"); 
                            exit(2);
                            }
                         *d=dim;
                         return array;
                         }
                      Lines 9-10,15-21 are unnecessary. If realloc fails then it is unlikely that malloc will succeed.

                      If you decide to keep malloc as a backup to realloc then you need to fix some run-time faults. You only enter this block if realloc fails ... that is, if array is set to NULL. That means that lines 16 and 19 will fail. You can fix these failures by assigning the realloc return value to a new variable to avoid corrupting array.

                      Also, line 11 should be checking tmp, not array.

                      Also, line 15 dereferences pointer d before it is verified to be non-NULL.

                      Comment

                      • stararic
                        New Member
                        • Jun 2009
                        • 14

                        #26
                        yes... I've fixed it, and the double free error too... now I'm checking arounf for some other problem, debbuggin, trying the program and commenting it... tks again

                        Comment

                        Working...