繁体   English   中英

使用 c 中的指针进行字符串输入会给我一个 function 中的分段错误。 相同的代码块适用于另一个 function?

[英]Taking string input using pointers in c gives me segmentation fault in one function. Same block of code works fine for another function?

所以我想使用 char* 指针将名称输入作为字符串。 我在网上查看并找到了一个解决方案,方法是使用 malloc 给我的指针 memory 然后使用scanf获取输入,如下所示:

  char *userInput = (char*)malloc(20 * sizeof(char));
  printf("\nEnter a name: ");
  scanf("%s",userInput);
  char *name = (char*)malloc(getLength(userInput)* sizeof(char));
  name = userInput;
  if(name == NULL){
    printf("Memory not allocated");
    exit(0);
  }
  free(userInput);

这行得通,所以我将它复制并粘贴到另一个需要类似输入的 function 中:

  char *userInput = (char*)malloc(20 * sizeof(char));
  printf("\nEnter a name: ");
  scanf("%s",userInput);
  char *searched = (char*)malloc(getLength(searched)* sizeof(char));
  searched = userInput;
  if(searched == NULL){
    printf("Memory not allocated");
    exit(0);
  }
  free(userInput);

但是当我运行这个 function 的代码时,它给了我“退出,分段错误”。

关于为什么它在我的第二个 function 中不起作用的任何想法?

编辑: getLength() 是一个 function ,它返回给定字符串的长度。

您在网上找到的代码,如果您正确地复制它,是错误的。 问题是您正在释放userInput ,即使searched指向 memory。

您应该在释放它之前将字符串从userInput复制到searched

但是没有必要对userInput使用动态分配。 您可以只使用本地数组。

分配searched时应该使用userInput的长度。 并且您需要加 1 为 null 终结器留出空间。

在尝试将userInput复制到其中之前,您应该检查分配是否成功。

  char userInput[20];
  printf("\nEnter a name: ");
  scanf("%19s",userInput); // limit input length to 19 so it fits in userInput
  char *searched = malloc((strlen(userInput)+1)* sizeof(char));
  if(searched == NULL){
    printf("Memory not allocated");
    exit(0);
  }
  strcpy(searched, userInput);

这两个代码块在这里有所不同:

char *name = (char*)malloc(getLength(userInput)* sizeof(char));
      ^^^^                           ^^^^^^^^^

char *searched = (char*)malloc(getLength(searched)* sizeof(char));
      ^^^^^^^^                           ^^^^^^^^^

第二种用途searched了两次。 因此,您可以正确修改原始代码。

但是,请注意两个代码块都是错误的。

代码有几个问题(两个例子)。

scanf("%s",userInput); 真的很糟糕,因为它让用户溢出你的缓冲区。 看看fgets或者至少做scanf("%19s",userInput);

这里:

char *name = (char*)malloc(getLength(userInput)* sizeof(char));
name = userInput;

malloc行是无用的,因为您之后立即用userInput覆盖name 所以所有malloc给你的是 memory 泄漏。

和这里

free(userInput);

您释放userInput指向的 memory。 但是,既然你做了name = userInput; name指向的也是memory。 所以在free之后,没有一个指针是有效的。

我的猜测是,而不是:

name = userInput;

你会想要

strcpy(name, userInput);

也就是说 - 我不知道getLength是什么,但也许malloc应该是:

char *name = (char*)malloc(1 + getLength(userInput)* sizeof(char));
                           ^^^

获取 memory 用于字符串终止。 至少这是你在使用strlen时所做的

所以:

  char *userInput = malloc(20);
  if(userInput == NULL){
    printf("Memory not allocated");
    exit(0);
  }

  printf("\nEnter a name: \n");
  scanf("%19s",userInput);

  char *searched = malloc(1 + strlen(userInput ));
  if(searched == NULL){
    printf("Memory not allocated");
    exit(0);
  }

  strcpy(searched, userInput);
  free(userInput);

但是......代码的真正目的是什么?

似乎searched应该保存(在动态分配的内存中)用户输入的字符串,并且动态分配的 memory 的数量应该正是保存字符串所需的量。

这在某些应用程序中可能有意义,但在您的情况下则不然!

第一个malloc用于 20 个字符。 因此,第二个malloc将用于 20 个或更少的字符。

Since malloc has a memory overhead and some alignment requirement, the amount of real memory required by, eg malloc(20) is more than 20 bytes. 换句话说 - malloc(20)malloc(10)使用的实际 memory的差异可能很小。 所以代码的整个想法是非常无用的 - 你不会通过执行第二个malloc和字符串复制来节省大量的 memory 。

所以你应该简单地做:

  char *searched = malloc(20);
  if(searched == NULL){
    printf("Memory not allocated");
    exit(0);
  }

  printf("\nEnter a name: \n");
  scanf("%19s",searched);

  // Go on using searched
  ...
  ...


  // Somewhere later in the code, call free
  free(searched);

仅当您的程序有时将很长的字符串作为输入并且有时很短时,原始代码才有意义。 在这种情况下,第一个malloc将用于更大的数字,例如 1000000 个字符,然后将输入复制到更小的缓冲区是有意义的。

暂无
暂无

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

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