简体   繁体   English

为什么内存不分配?

[英]Why does the memory not allocate?

My assignment is to allow the user to enter any input and print the occurrences of letters and words. 我的任务是允许用户输入任何输入并打印字母和单词的出现。 We also have to print out how many one letter, two, three, etc.. letter words are in the string. 我们还必须打印出字符串中有多少个字母,两个,三个等。

The word function has an access violation when dealing the array of pointers. 处理指针数组时,单词函数有访问冲突。 It looks like the malloc() function didn't properly allocate memory to my array of pointers and I'm not sure I did the coding right. 看起来malloc()函数未正确将内存分配给我的指针数组,并且我不确定我是否正确编写了代码。

I actually tried allocating memory to an index of the array, word[0] , and that index had memory that was properly allocated, but when I use a loop it never works, when I hover over the array and check each index it says "Bad PTR". 我实际上尝试将内存分配给数组的索引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);
}

What's wrong in my code? 我的代码有什么问题?

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

free(words);

Think what this code is doing; 想想这段代码在做什么; it loops until words == NULL , then tries to free (words) , which, if the loop has terminated, is NULL . 它循环直到words == NULL为止,然后尝试free (words) ,如果循环终止,则为NULL So, you're trying to free a NULL pointer. 因此,您正在尝试free NULL指针。

BTW. 顺便说一句。 You don't need to free strtok 's return value: Do I need to free the strtok resulting string? 您不需要释放strtok的返回值: 是否需要释放strtok结果字符串?

EDIT: The solution is this: 编辑:解决方案是这样的:

  1. for (i = 0; i< sizeof(point); i++) should be for (i = 0; i< strlen(point); i++) - sizeof(char*) is not the string's length, but the size of a char pointer on your system (4 or 8). for (i = 0; i< sizeof(point); i++)应该是for (i = 0; i< strlen(point); i++) - sizeof(char*)不是字符串的长度,而是char的大小系统上的指针(4或8)。
  2. Replace everything after that for loop above with: 将上述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]); 

That code is from Cool Guy's answer, except he had a bug there - the code was incrementing k twice. 该代码来自Cool Guy的答案,只是他在那里有一个错误-代码使k增加了两次。

Note that this code is pretty pointless as it is, it just allocates some memory, copies some stuff there, and frees that memory without doing anything, but I assume you want to do something else in the findWords function after that. 请注意,这段代码实际上是毫无意义的,它只是分配一些内存,在其中复制一些内容,然后不执行任何操作就释放该内存,但是我假设您想在那之后在findWords函数中执行其他操作。

strtok replaces all delimiters with '\\0' (= it modifies your input string). strtok将所有定界符替换为'\\0' (=会修改您的输入字符串)。

So if you want to build an array containing pointers to all the words in your input array you can simply write the following: 因此,如果要构建一个包含指向输入数组中所有单词的指针的数组,则只需编写以下内容:

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
    */
}

There is no need to allocate memory. 无需分配内存。

Running this little test 运行这个小测试

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);

shows the following (break point before leaving function findWords ): 显示以下内容(离开函数findWords之前的断点): 调试功能findWords

Within function findWords the contents of word are correct. 在函数findWords中, word的内容正确。

Try replacing 尝试更换

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);

with

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`

Also, 也,

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

should be 应该

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

or better 或更好

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

because sizeof(point) gives the size of a char* which is not want you want. 因为sizeof(point)给出了char*的大小,这是您不想要的。 So, use strlen . 因此,请使用strlen

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

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