2013-09-16 12 views
0

我想写一个程序,从字符串中删除任何字(用户可以输入此字)。程序的作品,但valgirnd给我一些错误消息:从键盘获取字符(内存分配)

==3009== Command: ./remove3 infile 
==3009== 
Type word that you want to remove from the file: 
go 
==3009== Invalid write of size 1 
==3009== at 0x4009CD: main (remove3.c:74) 
==3009== Address 0x51f1041 is 0 bytes after a block of size 1 alloc'd 
==3009== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3009== by 0x400947: main (remove3.c:45) 
==3009== 
==3009== Invalid read of size 1 
==3009== at 0x400AE6: DELTEword (remove3.c:115) 
==3009== by 0x400A39: main (remove3.c:90) 
==3009== Address 0x51f1041 is 0 bytes after a block of size 1 alloc'd 
==3009== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3009== by 0x400947: main (remove3.c:45) 
==3009== 
==3009== Invalid read of size 1 
==3009== at 0x400B16: DELTEword (remove3.c:118) 
==3009== by 0x400A39: main (remove3.c:90) 
==3009== Address 0x51f1041 is 0 bytes after a block of size 1 alloc'd 
==3009== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3009== by 0x400947: main (remove3.c:45) 
==3009== 
That Katharina and Petruchio should be married, 
And yet we hear not of our son-in-law. 
What will be said? what mockery will it be, 
To what bridegroom when the priest attends 
To speak the ceremonial rites of marriage! 
What says Lucentio to this shame of ours? 
==3009== 
==3009== HEAP SUMMARY: 
==3009==  in use at exit: 1 bytes in 1 blocks 
==3009== total heap usage: 50 allocs, 49 frees, 1,181 bytes allocated 
==3009== 
==3009== LEAK SUMMARY: 
==3009== definitely lost: 1 bytes in 1 blocks 
==3009== indirectly lost: 0 bytes in 0 blocks 
==3009==  possibly lost: 0 bytes in 0 blocks 
==3009== still reachable: 0 bytes in 0 blocks 
==3009==   suppressed: 0 bytes in 0 blocks 
==3009== Rerun with --leak-check=full to see details of leaked memory 
==3009== 
==3009== For counts of detected and suppressed errors, rerun with: -v 
==3009== ERROR SUMMARY: 95 errors from 3 contexts (suppressed: 2 from 2) 

也我想问一下主体。我不完全确定我从键盘获取字符的方式是否正确:例如,当我输入“go”时,一切正常,但“To”字不能删除,为什么?

这里是我的代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#define CHUNK 12 

char *getWord(FILE *infile); 
int DELTEword(char *word, char *KEYword); 

char *getWord(FILE *infile) 
{ 
    int length, cursor = 0, c; 
    char *word, *word2; 

    word = (char*)malloc(sizeof(char)*CHUNK); 
    if(word == NULL) return NULL; 

    length = CHUNK; 

     while((c = getc(infile)) != ' ' && !feof(infile)) 
     { 
      word[cursor] = c; 
      cursor++; 

      if(cursor >= length) 
      { 
       length += CHUNK; 
       word2 = (char*)realloc(word, length*sizeof(char)); 
       if(word2 == NULL) 
       { 
        free(word); 
        return NULL; 
       } 
       else word = word2; 
      } 
     } 

    word[cursor] = '\0'; 
    return word; 
} 

int main(int argc, char *argv[]) 
{ 
    char *word, c, *keyWord = (char*)malloc(sizeof(char)); 
    FILE *infile; 
    int length; 
    int size = 20; 

    if(argc != 2) 
    { 
     printf("\nMissing arguments.\n"); 
     abort(); 
    } 

    if(keyWord == NULL) return 0; 

    printf("Type word that you want to remove from the file:\n"); 

    length = 0; 

    while(1) 
    { 
     if(length == size) 
     { 
      keyWord = (char*)realloc(keyWord, size + 10); 
      size += 10; 
     } 

     c = getchar(); 

     if(c == '\n') break; 

     keyWord[length] = c; 
     length++; 
    } 

    infile = fopen(argv[1], "r"); 
    if(infile != NULL) 
    { 
     while(!feof(infile)) 
     { 
      word = getWord(infile); 
      if(word == NULL) 
      { 
       free(word); 
       break; 
      } 

      if(DELTEword(word, keyWord) == 1) 
      { 
       printf(word, infile); 
       printf(" "); 
       free(word); 
      } 
     } 
    } 
    else 
    { 
     printf("It is impossible to open the infile\n"); 
     abort(); 
    } 

    fclose(infile); 
    return 0; 
} 

int DELTEword(char *word, char *KEYword) 
{ 
    int i, k = 0, l = 0, length; 
    char *ptr; 

    if(word != NULL) 
    { 
     length = strlen(KEYword); 
     for(i = 0; word[i] != '\0'; i++) 
     { 
      if(word[i] == KEYword[k]) 
      { 
       l++; 
       k++; 
      } 
      else break; 

      if(l == length) 
      { 
       ptr = &word[i]; 
       memmove((ptr - length) + 1, ptr + 1, strlen((ptr - length) + 1)); 
       l = 0; 
       k = 0; 
      } 
     } 
     return 1; 
    } 
    else return 0; 
} 

感谢您的任何帮助。

回答

6

参照无效的写/读记录由Valgrind的:

您分配1个字节,并设置size20

char *word, c, *keyWord = (char*)malloc(sizeof(char)); 
... 
int size = 20; 

这应该以某种方式连接,例如是这样的:

int size = 20; 
char *word, c, *keyWord = malloc(size * sizeof(*keyWord)); 

此外,它似乎你没有分配alloc吃了“串”的0 - 终结者的房间。在C“字符串”中是字符数组,它们的最后一个有效字符由以下NUL字符指示。

所以你总是需要再分配那么“字符串”应该能容纳的最大字符数。


顺便说一句:在C没有必要投malloc/calloc/realloc,也不是建议:https://stackoverflow.com/a/605858/694576