内存分配怀疑类型指针指向char

时间:2011-09-27 19:31:39

标签: c pointers memory-management malloc arrays

该程序应该提示单词中的字母数(稍后输入),以便知道要分配多少空间。它似乎工作正常,但是如果你分配的内存少于要存储的单词所需的内存似乎并不重要。 这是一个我必须纠正的错误,还是因为这是指向char(char *)的指针是如何工作的?

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

int main() 
{
unsigned int a = 0;
printf("Enter the size of the word(0=exit) :");
scanf("%d",&a);
if(a==0){return 0;}
else
     {
      char *word = (char *)malloc(a*sizeof(char) + 1);
      if(word == NULL)
          {
           fprintf(stderr,"no memory allocated");
           return 1;
          }
      printf("Reserved %d bytes of space (accounting for the end-character).\nEnter your word: ", a*sizeof(char) + 1);
      scanf("%s", word);
      printf("The word is: %s\n", word);
     }

return 0;
}

好吧,我想我可能已经修好了,这样一来,用valgrind运行就没有显示出之前显示的错误。

char aux[]="";
  scanf("%s", aux);

  if(strlen(aux)>(a*sizeof(char) + 1))
     {
  fprintf(stderr,"Word bigger than memory allocated\nExiting program\n");
  return 1;
     }
  else
     {
      strcpy(word,aux);
      printf("The word is: %s\nAnd is %d characters long\n", word, strlen(word));
     }

现在我的疑问是:为什么我可以声明一个空的char数组(char aux [] =“”),然后使用“额外”内存而没有错误(在valgrind输出中)但char * aux =“”;给我一个分段错误? 我是C编程的新手,所以如果这是明显/愚蠢的问题,我很抱歉。 感谢。

3 个答案:

答案 0 :(得分:1)

似乎并不重要,但确实,如果您使用的空间超过分配空间,最终会以缓冲区溢出结束。您当前的实现可能会分配比实际请求更多的内容,也可能不会。您无法继续该行为,从不访问/使用未分配的内存。

根据定义也是sizeof( char ) == 1

答案 1 :(得分:1)

是的,您必须更正程序中的错误。

当您分配的内存少于您需要的内存,并且稍后访问该“额外”内存时,程序将进入未定义的行为模式。它似乎可以工作,或者它可能会崩溃,或者它可能会做任何意外的事情。基本上,在写入未分配的额外内存后, nothing 得到保证。

[更新:]

我从文件中读取任意长度字符串的建议如下。我不禁说它有点长,但由于标准C不提供一个很好的字符串数据类型,我不得不自己完成整个内存管理工作。所以这就是:

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

/** Reads a string from a file and dynamically allocates memory for it. */
int fagetln(FILE *f, /*@out*/ char **s, /*@out*/ size_t *ssize)
{
  char *buf;
  size_t bufsize, index;
  int c;

  bufsize = 128;
  if ((buf = malloc(bufsize)) == NULL) {
    return -1;
  }

  index = 0;
  while ((c = fgetc(f)) != EOF && c != '\n') {
    if (!(index + 1 < bufsize)) {
      bufsize *= 2;
      char *newbuf = realloc(buf, bufsize);
      if (newbuf == NULL) {
        free(buf);
        return -1;
      }
      buf = newbuf;
    }
    assert(index < bufsize);
    buf[index++] = c;
  }

  *s = buf;
  *ssize = index;
  assert(index < bufsize);
  buf[index++] = '\0';
  return ferror(f) ? -1 : 0;
}

int main(void)
{
  char *s;
  size_t slen;

  if (fagetln(stdin, &s, &slen) != -1) {
    printf("%zu bytes: %s\n", slen, s);
  }
  return 0;
}

答案 2 :(得分:0)

通常(但不总是)分配缓冲区的溢出会导致free缓冲区崩溃。如果你最后添加free(word),你可能会看到崩溃。