【问题标题】:What's wrong with strcpy()? (Segmentation fault) [duplicate]strcpy() 有什么问题? (分段错误)[重复]
【发布时间】:2011-02-21 13:41:56
【问题描述】:

这段代码中的strcpy() 有什么问题?

void process_filedata(char *filename)
{
  void* content;
  const char * buffer;
  char * temp;
  char * row;
  char * col;
  int lsize,buflen,tmp,num_scan; //num_scan - number of characters scanned
  int m=0,p=0,d=0,j=0; //m - machine, p - phase, d- delimiter, j - job

  FILE *file_pointer = fopen("machinetimesnew.csv","r");

  if(file_pointer == NULL)
  {
   error_flag =  print_error("Error opening file");

   if(error_flag) exit(1);
  }
  fseek(file_pointer, 0 ,SEEK_END);
  lsize = ftell(file_pointer);
  buflen = lsize;
  rewind(file_pointer);
 // content = (char*) malloc(sizeof(char)*lsize);
  fread(content,1,lsize,file_pointer);
  buffer = (const char*) content;
  strcpy(temp,buffer);
  row = strtok(temp,"\n");
  ...............
  ...............

我遇到了分段错误..

【问题讨论】:

  • 为什么malloc被评论了?
  • 还要意识到buffer 是不必要的。只需将content 设为char*
  • 为什么是一个字母的变量名?如果您花时间评论他们的名字,为什么不花额外的 2 秒时间来拯救自己和他人未来的困境并正确命名他们?
  • 谢谢大家。我会做出改变。

标签: c string


【解决方案1】:

您没有为 temp 分配任何空间。这是wild pointer

【讨论】:

    【解决方案2】:

    这里实际上有三个分段错误:

    fread(content,1,lsize,file_pointer);
    strcpy(temp,buffer);
    row = strtok(temp,"\n");
    

    第一个是fread(),它正在尝试写入就您的进程而言尚不存在的内存。

    第二个是strcpy(),(解释第一个)你试图复制一个指向空的指针。没有为temp 静态或动态分配内存(除了指针引用本身)。

    通过将temp 更改为如下所示(静态分配)来解决此问题:

    char temp[1024];
    

    或使用malloc() 为其动态分配内存(以及您的其他指针,因此它们实际上指向某些东西),content 也是如此。如果您在编译时知道所需的缓冲区大小,请使用静态分配。如果没有,请使用malloc()。 “知道”是另一个问题的主题。

    第三个是 strtok() ,它将修改 temp 原位(原位),它显然不能这样做,因为 temp 从未分配过。无论如何,一旦strtok() 完成,不要指望temp 是一样的。通过变量的名称,我假设您知道这一点。

    另外,初始化指针与为其分配内存是一回事:

    char *temp = NULL; // temp is initialized
    char *temp = (char *) malloc(size); // temp is allocated if malloc returns agreeably, cast return to not break c++
    

    最后,请养成使用strncpy() 而不是strcpy() 的习惯,这样更安全。

    【讨论】:

    • fread() 行也不正确,因为 content 也未初始化。
    • @caf,我确实说过 pointers :) 但是正在更新。
    【解决方案3】:

    strcpy 没有任何问题。你还没有初始化temp

    【讨论】:

    • 当然,但即使是“安全”版本也要求输入参数应该是实际值,而不是未初始化的垃圾。如果这里的strcpy 有什么问题,那么整个C 语言也有同样的问题。一旦第一个错误修复,我们可以担心buffer指向的数据是否真的包含NUL分隔符:-)
    【解决方案4】:

    还有一个错误。 fread 不会在缓冲区末尾添加 nul 字符。那是因为它只处理字节数组,而不是 nul 终止的字符串。所以你需要做这样的事情:

    content = malloc(lsize + 1);
    fread(content,1,lsize,file_pointer);
    content[lsize] = 0;
    temp = malloc(lsize + 1);
    strcpy(temp, content);
    

    或者这个:

    content = malloc(lsize);
    fread(content,1,lsize,file_pointer);
    temp = malloc(lsize + 1);
    memcpy(temp, content, lsize);
    temp[lsize] = 0;
    

    (另外,在实际代码中,您应该检查freadmalloc 的结果。)

    【讨论】:

      【解决方案5】:

      你没有为 temp 分配内存

      【讨论】:

        【解决方案6】:

        char * temp 尚未初始化,因此您尚未为其分配任何内存。

        尝试:

        temp = (char *)malloc(SIZE);

        其中SIZE 是您要为temp 分配的内存量

        【讨论】:

          【解决方案7】:

          这段代码让我很感兴趣:

          if(file_pointer == NULL)
          {
             error_flag =  print_error("Error opening file");
          
             if(error_flag) exit(1);
          }
          

          如果file_pointer为NULL,你不应该无条件退出吗?

          【讨论】:

          • 是的.. 那篇文章不完整。它是这样的。 error_flag = print_error(100); //ERROR 100: 打开文件出错!返回 1 if(error_flag) exit(1);
          • @blacktooth,在打印一个不错的错误并退出之前修改(可能的)非原子错误标志有什么用?此外,仅当标志为高时才达到exit() 有什么用?如果fopen() 返回 NULL 指针,为什么不保释?
          • 我想用这种方式编写 print_error 函数。 int print_error(int error_type) { switch(error_type) { case 100: printf("错误打开文件");返回 1;休息; case 101: printf("无效输入!使用默认值零"); //有些东西返回0;休息; .................................. .................. 是不是很糟糕想法?
          猜你喜欢
          • 2012-02-20
          • 2013-08-25
          • 2012-05-06
          • 2014-05-18
          • 2017-10-20
          • 1970-01-01
          • 2014-06-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多