简体   繁体   English

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

[英]Memory allocation doubt with type pointer to char

This program is supposed to prompt for the number of letters in a word(to be entered later) so it knows how much space to allocate. 该程序应该提示单词中的字母数(稍后输入),以便知道要分配多少空间。 It seems to work OK, however it doesn't seem to matter if you allocate less memory than needed for the word to be stored. 它似乎工作正常,但是如果你分配的内存少于要存储的单词所需的内存似乎并不重要。 Is it a bug that I must correct or is it because that's how pointer to char (char *) works? 这是一个我必须纠正的错误,还是因为这是指向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;
}

All right i think i might have fixed it, this way, running with valgrind shows none of the errors that it showed earlier. 好吧,我想我可能已经修好了,这样一来,用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));
     }

Now my doubt is: why can I declare an empty char array(char aux[] = ""), and then use "extra" memory with no errors (in valgrind output) yet char *aux = ""; 现在我的疑问是:为什么我可以声明一个空的char数组(char aux [] =“”),然后使用“额外”内存而没有错误(在valgrind输出中)还有char * aux =“”; gives me a segmentation fault? 给我一个分段错误? I'm very new to C programming so I'm sorry if it's obvious/ dumb question. 我是C编程的新手,所以如果这是明显/愚蠢的问题,我很抱歉。 Thanks. 谢谢。

It doesn't seem to matter but it does , if you use more space than allocated you will eventually end with a buffer overrun. 这似乎并不重要,但它确实 ,如果使用的不是分配,您将最终与缓冲区溢出结束更大的空间。 It's possible that your current implementation allocates a bit more than what you actually request, its also possible that it doesn't. 您当前的实现可能会分配比实际请求更多的内容,也可能不会。 You cannot relay on that behavior, never access/use memory that wasn't allocated. 您无法继续该行为,从不访问/使用未分配的内存。

Also sizeof( char ) == 1 by definition. 根据定义, sizeof( char ) == 1

Yes, you must correct that bug in your program. 是的,您必须更正程序中的错误。

When you allocate less memory than you need, and later access that "extra" memory, the program goes into undefined behavior mode. 当您分配的内存少于您需要的内存,并且稍后访问该“额外”内存时,程序将进入未定义的行为模式。 It may seem to work, or it may crash, or it may do anything unexpected. 它似乎可以工作,或者它可能会崩溃,或者它可能会做任何意外的事情。 Basically, nothing is guaranteed after you write to the extra memory that you didn't allocate. 基本上,在写入未分配的额外内存后, 没有任何保证。

[Update:] [更新:]

My proposal to read a string of arbitrary length from a file is the following code. 我建议从文件中读取任意长度的字符串是以下代码。 I cannot help that it is somewhat long, but since standard C doesn't provide a nice string data type, I had to do the whole memory management thing on my own. 我不禁说它有点长,但由于标准C不提供一个很好的字符串数据类型,我不得不自己完成整个内存管理工作。 So here it is: 所以这里是:

#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;
}

Usually (but not always) the overflows of allocated buffers causing a crash when you free the buffer. 通常(但不总是)分配缓冲区的溢出会在free缓冲区时导致崩溃。 If you would add free(word) at the end, you will probably see the crash. 如果你最后添加free(word) ,你可能会看到崩溃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM