为什么我不能在C中使用[]为字符串分配内存?

时间:2012-05-03 02:24:52

标签: c arrays string memory

对于getline()函数,我尝试了两种方法为字符串分配内存空间,但是第一种方法有效,第二种方法没有。任何人都可以解释为什么第二个不起作用?

第一个

#include <stdio.h>

int main()
{
  int bytes_read;
  int nbytes = 100;
  char *my_string;

  puts ("Please enter a line of text.");

  /* These 2 lines are the heart of the program. */
  my_string = (char *) malloc (nbytes + 1);
  bytes_read = getline (&my_string, &nbytes, stdin);

  if (bytes_read == -1)
    {
      puts ("ERROR!");
    }
  else
    {
      puts ("You typed:");
      puts (my_string);
    }

  return 0;
}

第二个:

#include <stdio.h>
int main()
{
  int bytes_read;
  int nbytes = 100;
  char my_string[nbytes+1];

  puts ("Please enter a line of text.");

  /* These 2 lines are the heart of the program. */
  bytes_read = getline (&my_string, &nbytes, stdin);

  if (bytes_read == -1)
    {
      puts ("ERROR!");
    }
  else
    {
      puts ("You typed:");
      puts (my_string);
    }

  return 0;
}

第二个可以编译,但是当我执行它时:

bash-3.2$ ./a.out 
Please enter a line of text.
lsdfa
Bus error: 10

它说总线错误:10

我不知道可能的原因是什么,有人可以帮助我吗?

5 个答案:

答案 0 :(得分:4)

The signature for getline requires a pointer to a char* so that it may be modified。这是因为getline应该被允许在realloc上调用char*,或者如果您传递char*指向0 {<1}},则可以分配char* / p>

  

getline()从流中读取整行,存储缓冲区的地址         将文字包含在*lineptr

中      

...

     

在任何一种情况下,成功通话后,*lineptr*n都会更新为         分别反映缓冲区地址和分配的大小

在第一种情况下,一切都很好,因为您传递给getline的指针可以被修改。

在第二种情况下,您传递的指针指向char数组,该数组本身无法修改。正如您所发现的,遗憾的是&my_string最终看起来像char**,因此编译器不会抱怨(但可能会-Wall)。

基本上,由于getline需要能够修改lineptr指向的内容,因此在第二种情况下无法完成(因此总线错误)。

答案 1 :(得分:3)

阅读getline()的联机帮助页:

Exerpt:

  

或者,在调用getline()之前,* lineptr可以包含一个指向malloc(3)分配缓冲区* n字节大小的指针。

所以getline()特别假定传递给它的缓冲区已经分配了malloc,以便在必要时可以将其调整为更大的大小。

你应该得到一个编译器警告,例如这个警告,你会发现你调用函数的方式有问题:

  

警告:从不兼容的指针类型

传递'getline'的参数1

答案 2 :(得分:2)

我实际上无法理解这一点。你的例子都不应该从我能说的内容中编译出来......事实上它并不接近它。这样做:

int main() {

  std::string line;

...
  std::getline(std::cin, line);

...
}

不必乱用malloc,new,任何......

包括iostream,而不是stdio.h

答案 3 :(得分:0)

使用'new'关键字进行动态初始化:

char* my_string = new char[nBytes + 1];

答案 4 :(得分:0)

更正版本:

http://linux.die.net/man/3/getline

#include <stdio.h>
#define BUFLEN 100

int main()
{
  int bytes_read;
  int nbytes = BUFLEN;
  char *my_string = NULL;

  puts ("Please enter a line of text.");

  /* These 2 lines are the heart of the program. */
  bytes_read = getline (&my_string, &nbytes, stdin);

  if (bytes_read == -1)
    {
      puts ("ERROR!");
    }
  else
    {
      puts ("You typed:");
      puts (my_string);
    }

  return 0;
}

坦率地说,我更喜欢“fgets()”而不是“getline()”:

#include <stdio.h>
#define BUFLEN 100

int main()
{
  char my_string[BUFLEN+1];

  puts ("Please enter a line of text.");

  /* These 2 lines are the heart of the program. */
  fgets (my_string, BUFLEN, stdin);
  ...

如果您使用的是C ++ - land,那么最好使用std :: string。