为什么内存不分配?
Why does the memory not allocate?
我的任务是允许用户输入任何内容并打印出现的字母和单词。我们还必须打印出字符串中有多少个字母、两个、三个等字母单词。
处理指针数组时,字函数存在访问冲突。看起来 malloc()
函数没有正确地为我的指针数组分配内存,我不确定我的编码是否正确。
我实际上尝试将内存分配给数组的索引,word[0]
,并且该索引具有正确分配的内存,但是当我使用循环时它永远不会工作,当我将鼠标悬停在数组上并且检查它说的每个索引 "Bad 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 '[=10=]'
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
的 return 值:Do I need to free the strtok resulting string?
编辑:解决方案是这样的:
for (i = 0; i< sizeof(point); i++)
应该是 for (i = 0; i< strlen(point); i++)
- sizeof(char*)
不是字符串的长度,
但是你系统上的 char 指针的大小(4 或 8)。
将上面 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
之后的功能。
尝试替换
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
.
strtok
将所有分隔符替换为 '[=13=]'
(= 它会修改您的输入字符串)。
因此,如果您想构建一个包含指向输入数组中所有单词的指针的数组,您可以简单地编写以下内容:
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
中 word
的内容是正确的。
我的任务是允许用户输入任何内容并打印出现的字母和单词。我们还必须打印出字符串中有多少个字母、两个、三个等字母单词。
处理指针数组时,字函数存在访问冲突。看起来 malloc()
函数没有正确地为我的指针数组分配内存,我不确定我的编码是否正确。
我实际上尝试将内存分配给数组的索引,word[0]
,并且该索引具有正确分配的内存,但是当我使用循环时它永远不会工作,当我将鼠标悬停在数组上并且检查它说的每个索引 "Bad 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 '[=10=]'
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
的 return 值:Do I need to free the strtok resulting string?
编辑:解决方案是这样的:
for (i = 0; i< sizeof(point); i++)
应该是for (i = 0; i< strlen(point); i++)
-sizeof(char*)
不是字符串的长度, 但是你系统上的 char 指针的大小(4 或 8)。将上面
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
之后的功能。
尝试替换
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
.
strtok
将所有分隔符替换为 '[=13=]'
(= 它会修改您的输入字符串)。
因此,如果您想构建一个包含指向输入数组中所有单词的指针的数组,您可以简单地编写以下内容:
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
中 word
的内容是正确的。