簡體   English   中英

為什么內存不分配?

[英]Why does the memory not allocate?

我的任務是允許用戶輸入任何輸入並打印字母和單詞的出現。 我們還必須打印出字符串中有多少個字母,兩個,三個等。

處理指針數組時,單詞函數有訪問沖突。 看起來malloc()函數未正確將內存分配給我的指針數組,並且我不確定我是否正確編寫了代碼。

我實際上嘗試將內存分配給數組的索引word[0] ,並且該索引具有正確分配的內存,但是當我使用循環時,它將永遠無法正常工作,當我將鼠標懸停在數組上並檢查每個索引時,它說“ PTR錯誤”。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void findLetters(char *ptr);
void findWords(char *point);


int main()
{
    char textStream[100]; //up to 98 characters and '\n\ and '\0'

    printf("enter some text\n");
    if (fgets(textStream, sizeof (textStream), stdin)) //input up to 99 characters
    {
        findLetters(textStream);
        findWords(textStream);
    }
    else
    {
        printf("fgets failed\n");
    }

    return 0;
}

void findLetters(char *ptr) //find occurences of all letters
{ /*Works fine*/ }

void findWords(char *point)
{
    int i = 0;
    int k = 0;
    int count = 0;
    int j = 0;
    int space = 0;
    int c = 0;
    char *word[50];
    char word1[50][100];
    char* delim = "{ } . , ( ) ";

    for (i = 0; i< sizeof(point); i++) //counts # of spaces between words
    {
        if ((point[i] == ' ') || (point[i] == ',') || (point[i] == '.'))
        {
            space++;
        }
    }
    char *words = strtok(point, delim);
    for(;k <= space; k++)
    {
        word[k] = malloc((words+1) * sizeof(*words));
    }

        while (words != NULL)
        {
            printf("%s\n",words);
            strcpy(words, word[j++]);
            words = strtok(NULL, delim);
        }

    free(words);
}

我的代碼有什么問題?

 while (words != NULL)
 {
      printf("%s\n",words);
      strcpy(words, word[j++]);
      words = strtok(NULL, delim);
 }

free(words);

想想這段代碼在做什么; 它循環直到words == NULL為止,然后嘗試free (words) ,如果循環終止,則為NULL 因此,您正在嘗試free NULL指針。

順便說一句。 您不需要釋放strtok的返回值: 是否需要釋放strtok結果字符串?

編輯:解決方案是這樣的:

  1. for (i = 0; i< sizeof(point); i++)應該是for (i = 0; i< strlen(point); i++) - sizeof(char*)不是字符串的長度,而是char的大小系統上的指針(4或8)。
  2. 將上述for循環之后的所有內容替換for

     char *words = strtok(point, delim); for (; k <= space && words != NULL; k++) { if (k >= 50) //size of the word array { puts ("Too many words!"); return; } word[k] = malloc(strlen(words) + 1); strcpy(word[k], words); words = strtok(NULL, delim); } for (int i = 0; i < k; i++) free(word[i]); 

該代碼來自Cool Guy的答案,只是他在那里有一個錯誤-代碼使k增加了兩次。

請注意,這段代碼實際上是毫無意義的,它只是分配一些內存,在其中復制一些內容,然后不執行任何操作就釋放該內存,但是我假設您想在那之后在findWords函數中執行其他操作。

strtok將所有定界符替換為'\\0' (=會修改您的輸入字符串)。

因此,如果要構建一個包含指向輸入數組中所有單詞的指針的數組,則只需編寫以下內容:

void findWords(char *point)
{
    int count = 0;
    char *word[50];
    char* delim = "{ } . , ( ) ";
    char *words = strtok(point, delim);

    count = 0;
    while (words != NULL)
    {
        word[count] = words;
        count++;

        printf("%s\n",words);
        words = strtok(NULL, delim);

        if (count >= 50)   // word is limited to char *word[50] !!!
        {
             printf("too much words!\n");
             break;
        }
    }

    /*
    ** now count contains the number of words and
    ** word[0 .. (count - 1)] contains the words
    */
}

無需分配內存。

運行這個小測試

char test1[] = "hallo test, 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50";
char test2[] = "hallo test (2)";

findWords(test1);
findWords(test2);

顯示以下內容(離開函數findWords之前的斷點): 調試功能findWords

在函數findWords中, word的內容正確。

嘗試更換

for(;k <= space; k++)
{
    word[k] = malloc((words+1) * sizeof(*words));
}

    while (words != NULL)
    {
        printf("%s\n",words);
        strcpy(words, word[j++]);
        words = strtok(NULL, delim);
    }

free(words);

for(;k <= space && words != NULL; k++)
{
    //word[k] = malloc((words+1) * sizeof(*words)); //Doesn't do what you think; You need strlen
    word[k] = malloc( strlen(words) + 1); //+1 for the NUL-terminator

    printf("%s\n",words);
    strcpy(word[k], words); //Arguments were mixed up. You want the opposite
    words = strtok(NULL, delim);
}

for(int i = 0; i < k; i++)
    free(word[i]);       //Free each index as you've allocated each of them not `words`

也,

for (i = 0; i< sizeof(point); i++)

應該

for (i = 0; i< strlen(point); i++)

或更好

int len = strlen(point);
for (i = 0; i < len; i++)

因為sizeof(point)給出了char*的大小,這是您不想要的。 因此,請使用strlen

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM