【问题标题】:Segmentation error when trying to copy from one memory location to another尝试从一个内存位置复制到另一个内存位置时出现分段错误
【发布时间】:2019-02-02 14:33:10
【问题描述】:

我必须编写一个函数来重现 c https://www.tutorialspoint.com/c_standard_library/c_function_strcpy.htm 中 strcpy 的行为

如果我对这个函数的理解正确,它会将字符串从源内存位置复制到目标内存位置,并返回指向目标内存位置的指针。

这里是我生成的代码:

#include <stdio.h>

char *ft_strcpy(char *dest, char *src)
{
  char *mem = dest;
  while (*src != '\0')
  {
    *dest = *src;
    src++;
    dest++;
  }
  *dest = '\0';
  return mem;
}

int main()
{
  char word[5] = "word";
  printf("%s \n", word);
  printf("word address is %p \n", word);
  char *dest;
  printf("dest address is %p", dest);
  ft_strcpy(dest, word);
  while (*dest != '\0'){
    printf("%c", *dest);
    dest++;
  }
}

为了测试我的代码,我声明了一个包含“word”和指针 *dest 的字符数组。

但是,当我运行我的代码时,我得到一个 59873 分段错误。我认为是这条线导致了错误:

*dest = *src;

但是我不明白这条线有什么问题。对我来说,这一行的意思是“将 src 指针指向的值复制到 dest 指向的内存位置”。

谁能解释一下这段代码出了什么问题

【问题讨论】:

    标签: c pointers segmentation-fault


    【解决方案1】:
    1 . Your *dest is dangling pointer in main so first you need to store some valid address into it by using malloc() or other method .
    2 . Storing address of string from code section in array is bad programming practice .
    3 . Check the modified code .
    
    #include <stdio.h>
    #include <string.h>  /* for strcpy */
    #include <stdlib.h> /* for malloc */ 
    char *ft_strcpy(char *dest, char *src)  
    {  
      char *mem = dest;  
      while (*src != '\0')  
      {  
        *dest = *src;  
        src++;
        dest++;
      }
      *dest = '\0';
      return mem;
    }
    
    int main()
    {
      char word[5]; strcpy(word,"word");
      printf("%s \n", word);
      printf("word address is %p \n", word);
      char *dest=malloc(strlen(word)+1); //+1 for null terminating character .
      printf("dest address is %p", dest);
      char *temp=dest;
      ft_strcpy(dest, word);
      while (*dest != '\0'){
        printf("%c", *dest);
        dest++;
      }
    free(temp);
    }
    

    【讨论】:

      【解决方案2】:

      你永远不会给dest 一个值,所以它的值是未定义的。因此,您的程序具有未定义的行为。更具体地说:char* dest; 只是给你一个“指向字符的指针”,但实际上并没有设置值。

      char c = 'A';
      char *dest = &c;
      

      是 100% 有效的代码(尽管您不能使用 dest)。您需要将dest 指向足够大的内存块以满足您的目的。您可以使用动态内存分配:

      dest = malloc(32); // 32 is a randomly selected value
      // don't forget a NULL check and to free() once done.
      

      但是,如果您现在想避免那些蠕虫,那么使用静态缓冲区将起作用。

      char block[10]; // 10 is randomly selected to work in your example
      char *dest = block;
      

      char dest[10] = { 0 }; // initializes all to 0
      // but now you can't do "dest++" etc.
      

      喜欢:

      int main()
      {
        char word[5] = "word";
        char block[10]; // 10 is randomly selected to work in your example
        char *dest = block;
      
        printf("%s \n", word);
        printf("word address is %p \n", word);
      
        printf("dest address is %p", dest)
        ft_strcpy(dest, word);
        ...
      

      【讨论】:

      • 谢谢@john,但 char *dest 不应该声明一个指针并保留内存分配吗?
      • @DavidGeismar No. char* dest 只是给你一个没有设置任何东西的指针。
      • 我实际上得到了一个错误,char dest[10] cannot increase value of type 'char [10]'
      • 不要更改ft_strcpy,只需更改“分配”,如图所示。问题出在main 中,您将未初始化的值传递给您的复制函数。你需要解决这个问题。
      • 我已经尝试按照你说的做,并使用 char block[10] char *dest = block 将 mem 分配给 dest。但是最后它没有打印我复制的字符链,因为它应该在 main 函数末尾的 while 循环中执行...
      【解决方案3】:
      char *dest;
      printf("dest address is %p", dest);
      ft_strcpy(dest, word);
      

      您的第一个问题是您将dest 发送到ft_strcpyprintf 而不分配任何值。它的实际价值是不确定的,很可能是任何东西。

      dest 需要是一个足够大的内存指针以容纳word

      char *dest = malloc(strlen(word) + 1)
      

      如果我们为空终止符分配word + 1 字节的长度,ft_strcpy 将正常工作。

      那你只需要记住使用免费

      free(dest);
      

      就是这样。

      您唯一的问题是 ft_strcpydest 不是有效指针时通过取消引用 *dest 来执行未定义。

      【讨论】:

      • 嘿@abigail 我不能使用任何库所以我不能使用malloc
      • 那么你应该使用上面的另一个答案来创建一个静态缓冲区,那么你只需要希望ft_strcpy 不会超过它的大小。
      猜你喜欢
      • 2021-02-11
      • 1970-01-01
      • 2017-11-23
      • 2014-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      相关资源
      最近更新 更多