簡體   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