2015-02-18 3 views
1

Я разработал динамическую строку, которая может быть изменена на языке программирования c, но у меня есть некорректное чтение, которое мне сообщает valgrind, но я попытался выяснить, почему, но я не смог:недействительная запись о размере 8 valgrind

PS: программа работает.

dstring.c

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

#include "error.h" 
#include "dstring.h" 

#define DEFAULT_SIZE 512 

struct dstring { 
    char *str; 
    char *estr; 
    size_t msize; 
}; 

lgw_return lgw_init_dstring(struct dstring **dstr, const char *data) 
{ 
    size_t len; 

    if((*dstr = malloc(sizeof *dstr)) == NULL) 
     return LGW_ERROR_MALLOC;   

    if(data != NULL) { 
     // intiliaze dstring with value of data 
     len = strlen(data); 

     if(((*dstr)->str = malloc(len + DEFAULT_SIZE)) == NULL) { 
      free(*dstr); 
      return LGW_ERROR_MALLOC; 
     } 

     strcpy((*dstr)->str, data); 
     (*dstr)->estr = (*dstr)->str + len; 
     (*dstr)->msize = len + DEFAULT_SIZE; 
    } 
    else { 
     // create empty dstring 
     if(((*dstr)->str = malloc(DEFAULT_SIZE)) == NULL) { 
      free(*dstr); 
      return LGW_ERROR_MALLOC; 
     } 

     *((*dstr)->str) = '\0'; 
     (*dstr)->estr = (*dstr)->str; 
     (*dstr)->msize = DEFAULT_SIZE; 
    } 

    return LGW_SUCCESS; 
} 

lgw_return lgw_destroy_dstring(struct dstring **dstr) 
{ 
    free((*dstr)->str); 
    free(*dstr); 
    *dstr = NULL; 
    return LGW_SUCCESS; 
} 

lgw_return lgw_write_dstring(struct dstring *dstr, const char *data, size_t off) 
{ 
    size_t datalen = strlen(data); 
    char *tmp_str; 

    //if offset is beyond the '\0' char return error 
    if(off > dstr->estr - dstr->str) 
     return LGW_OUT_OF_RANGE; 

    if(off + datalen > dstr->msize) { 

     if((tmp_str = realloc(dstr->str, dstr->msize + 
      datalen + DEFAULT_SIZE)) == NULL) 

      return LGW_ERROR_MALLOC;  

     dstr->str = tmp_str; 
     dstr->msize += datalen + DEFAULT_SIZE; 
    } 

    strcpy(dstr->str + off, data); 
    dstr->estr = dstr->str + off + datalen; 

    return LGW_SUCCESS; 
} 

lgw_return lgw_append_dstring(struct dstring *dstr, const char *data) 
{ 
    return lgw_write_dstring(dstr, data, dstr->estr - dstr->str); 
} 
const char *lgw_get_dstring(struct dstring *dstr) 
{ 
    return (const char *)(dstr->str); 
} 

dstring.h

#ifndef DSTRING_H_INCLUDED 
#define DSTRING_H_INCLUDED 

#include "error.h" 

typedef struct dstring DynamicString; 

lgw_return lgw_init_dstring(struct dstring **dstr, const char *data); 
lgw_return lgw_destroy_dstring(struct dstring **dstr); 
lgw_return lgw_write_dstring(struct dstring *dstr, const char *data, size_t off); 
lgw_return lgw_append_dstring(struct dstring *dstr, const char *data); 
const char *lgw_get_dstring(struct dstring *dstr); 

#endif 

main.c

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

#include "error.h" 
#include "dstring.h" 


int main() 
{ 
    lgw_return rc; 
    DynamicString *s; 

    if((rc =lgw_init_dstring(&s, "test")) != LGW_SUCCESS) { 
     fprintf(stderr, "ERROR : %s", lgw_strerror(rc)); 
     exit(EXIT_FAILURE); 
    } 

    lgw_append_dstring(s, "123"); 
    const char *str = lgw_get_dstring(s); 

    printf("value is : %s\n", str); 
    lgw_destroy_dstring(&s); 
} 

выход Valgrind

==6919== Memcheck, a memory error detector 
==6919== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==6919== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info 
==6919== Command: ./a.out 
==6919== 
==6919== Invalid write of size 8 
==6919== at 0x40084A: lgw_init_dstring (dstring.c:33) 
==6919== by 0x400AD7: main (test.c:14) 
==6919== Address 0x51de048 is 0 bytes after a block of size 8 alloc'd 
==6919== at 0x4C28C20: malloc (vg_replace_malloc.c:296) 
==6919== by 0x4007A0: lgw_init_dstring (dstring.c:20) 
==6919== by 0x400AD7: main (test.c:14) 
==6919== 
==6919== Invalid write of size 8 
==6919== at 0x400860: lgw_init_dstring (dstring.c:34) 
==6919== by 0x400AD7: main (test.c:14) 
==6919== Address 0x51de050 is 8 bytes after a block of size 8 alloc'd 
==6919== at 0x4C28C20: malloc (vg_replace_malloc.c:296) 
==6919== by 0x4007A0: lgw_init_dstring (dstring.c:20) 
==6919== by 0x400AD7: main (test.c:14) 
==6919== 
==6919== Invalid read of size 8 
==6919== at 0x400A30: lgw_append_dstring (dstring.c:87) 
==6919== by 0x400B21: main (test.c:19) 
==6919== Address 0x51de048 is 0 bytes after a block of size 8 alloc'd 
==6919== at 0x4C28C20: malloc (vg_replace_malloc.c:296) 
==6919== by 0x4007A0: lgw_init_dstring (dstring.c:20) 
==6919== by 0x400AD7: main (test.c:14) 
==6919== 
==6919== Invalid read of size 8 
==6919== at 0x40093C: lgw_write_dstring (dstring.c:65) 
==6919== by 0x400A59: lgw_append_dstring (dstring.c:87) 
==6919== by 0x400B21: main (test.c:19) 
==6919== Address 0x51de048 is 0 bytes after a block of size 8 alloc'd 
==6919== at 0x4C28C20: malloc (vg_replace_malloc.c:296) 
==6919== by 0x4007A0: lgw_init_dstring (dstring.c:20) 
==6919== by 0x400AD7: main (test.c:14) 
==6919== 
==6919== Invalid read of size 8 
==6919== at 0x40096F: lgw_write_dstring (dstring.c:68) 
==6919== by 0x400A59: lgw_append_dstring (dstring.c:87) 
==6919== by 0x400B21: main (test.c:19) 
==6919== Address 0x51de050 is 8 bytes after a block of size 8 alloc'd 
==6919== at 0x4C28C20: malloc (vg_replace_malloc.c:296) 
==6919== by 0x4007A0: lgw_init_dstring (dstring.c:20) 
==6919== by 0x400AD7: main (test.c:14) 
==6919== 
==6919== Invalid write of size 8 
==6919== at 0x400A11: lgw_write_dstring (dstring.c:80) 
==6919== by 0x400A59: lgw_append_dstring (dstring.c:87) 
==6919== by 0x400B21: main (test.c:19) 
==6919== Address 0x51de048 is 0 bytes after a block of size 8 alloc'd 
==6919== at 0x4C28C20: malloc (vg_replace_malloc.c:296) 
==6919== by 0x4007A0: lgw_init_dstring (dstring.c:20) 
==6919== by 0x400AD7: main (test.c:14) 
==6919== 
value is : test123 
==6919== 
==6919== HEAP SUMMARY: 
==6919==  in use at exit: 0 bytes in 0 blocks 
==6919== total heap usage: 2 allocs, 2 frees, 524 bytes allocated 
==6919== 
==6919== All heap blocks were freed -- no leaks are possible 
==6919== 
==6919== For counts of detected and suppressed errors, rerun with: -v 
==6919== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0) 
+2

Хотя ** Chostakovitch ** ответ 's неправильно, оно должно быть '* Dstr = таНос (SizeOf (** Dstr))' в факт. –

+0

Извините за мой ответ, я понял, что 'dstr' не был типом, а сам указатель. Я удалил его. Ихараб прав. – Chostakovitch

ответ

3

Вы указываете неправильный объем памяти для выделения структуры:

if((*dstr = malloc(sizeof *dstr)) == NULL) 

С Dstr есть (структура DStR **), то SizeOf (* Dstr) является размер указателя, но не размер структуры. Чтобы исправить это, Вы могли бы хотеть написать его таким образом:

if((*dstr = malloc(sizeof **dstr)) == NULL) 
+0

да, точно ... –

Смежные вопросы