0
votes

valgrind report the invalid write of size 8

at 0x4007A0:ArrayCstringPush

by 0x4008F8:main

Address 0x4A0A450 is 0 bytes after a block of size 8 alloc'd

at 0x4905D27: calloc

by 0x.......: ArrayCstringNew

by 0x.......: main

why report this error ? and how to fix the problem. thanks!

  //arrayOfCstring.h

  typedef struct {
  int numOfElems;
  int size;
  int allocSize;
  char** elems;
  //size_t elemAllocSize;

 } ArrayCstring;

void ArrayCstringNew(ArrayCstring *s,int allocS)
{
 s->allocSize=allocS;
 s->numOfElems=0;  
 s->size=0;
 s->elems=(char **)calloc(s->allocSize,sizeof(int));
 assert(s->elems!=0);
 }
 void ArrayCstringGrow(ArrayCstring *s){
     if(((s->numOfElems)+1)>(s->allocSize)){
     s->allocSize=(s->allocSize)*2;
     s->elems=(char**)realloc(s->elems,(s->allocSize)*sizeof(int));
      }
 }
   void ArrayCstringPush(ArrayCstring *s,char *elem,int lengthOfElem){
    ArrayCstringGrow(s);
    //(s->elems)[s->numOfElems]=(char *)malloc(lengthOfElem);

    (s->elems)[s->numOfElems]=(char *)calloc(lengthOfElem,sizeof(int));
    printf("start to realloc numOfElem is %i, allocSize is %i\n",s->numOfElems,s->allocSize); 
    strcpy((s->elems)[s->numOfElems],elem);
    //assert((s->elems)!=0);
    printf("push %s\n",s->elems[s->numOfElems]);
    s->numOfElems+=1;
  }
  char *ArrayCstringIndex(ArrayCstring *s,int i)
  {
  //assert((s->numOfElems)>i);
    return s->elems[i];
    }

 void ArrayCstringDelete(ArrayCstring *s)
 {
  int a=0;
  for(;a<(s->numOfElems);++a){
   free((s->elems)[a]);
                        }
   free(s->elems);
   }


    //MAIN FUNCTION
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include "arrayOfCstring.h"

       int main(void){
        ArrayCstring *ep;
        ep =(ArrayCstring *)malloc(1000);
        ArrayCstringNew(ep,2);
        ArrayCstringPush(ep,"ysdfsd",7);
        printf("start to \n");
        ArrayCstringPush(ep,"1213423",8);
        int a;
        for(a=0;a<2;++a){
         char *str=ArrayCstringIndex(ep,a);
         printf("string is %s\n",str);
                  }
         ArrayCstringDelete(ep);
        }
2

2 Answers

0
votes

There are several misuses of malloc() and calloc() in the code which may be the cause of the invalid write.

Change:

ep =(ArrayCstring *)malloc(1000);

s->elems=(char **)calloc(s->allocSize,sizeof(int));

(s->elems)[s->numOfElems]=(char *)calloc(lengthOfElem,sizeof(int));

to:

ep = malloc(sizeof(ArrayCstring));

s->elems= calloc(s->allocSize,sizeof(char*));

(s->elems)[s->numOfElems]= strdup(elem);

respectively.

0
votes

Instead of allocating your array like

ep = (ArrayCstring *) malloc (1000);

you have to take care that the allocated size is a multiple of ArrayCstring, otherwise you might write beyond the allocated memory when accessing the last element.

I suggest

ep = (ArrayCstring *) malloc (1000 * sizeof (ArrayCstring));