我是学习C的新手,我正在练习内存分配和指针,但是我遇到了一个我无法解决的问题。当我调试下面的代码时,我收到一条错误,指出“无法访问内存地址”行vowelStore [x] = vowelA;
char *DissVowel(char phrase[50])
{
char vowelStore[50];
for(int x=0; x< strlen(phrase); x++)
{
switch(phrase[x])
{
char *vowelA = malloc(sizeof(*vowelA));
case 'a':
vowelA = phrase[x];
vowelStore[x] = vowelA;
free(vowelA);
break;
default:
break;
}
}
return vowelStore;
}
基本上,这个函数接受一个字符数组(一个字符串短语),然后遍历每个字符,如果当前字符是“a”,则分配一个内存片段,并将“a”存储在分配空间。接下来,包含“a”的此空间的地址将存储在一个单独的数组中,该数组将包含多个地址。然后该函数返回该地址数组。
非常感谢任何帮助!
答案 0 :(得分:0)
您的代码存在许多问题。
char *DissVowel(char phrase[50])
这是合法但有误导性的。 C实际上没有数组参数。如果你定义了一个看起来像数组参数的东西,正如你在这里所做的那样,它被“调整”成为指针参数 - 并且长度被静静地忽略。以上完全等同于:
char *DissVowel(char *phrase)
for(int x=0; x< strlen(phrase); x++)
这是合法但效率低下的。 strlen()
必须从头开始扫描字符串,以找到标记字符串结尾的终止'\0'
空字符。您在每次迭代时调用strlen
。将字符串长度保存在变量中并在条件中测试,或使用不同的条件,例如phrase[x] != '\0'
。 (非常小的一点:i
是用作索引的迭代变量的更常规名称。)
switch(phrase[x])
{
char *vowelA = malloc(sizeof(*vowelA));
case 'a':
/* ... */
break;
default:
break;
}
switch
语句本质上是一个计算goto
。执行switch
后,它会直接跳转到case 'a':
标签或default:
标签,跳过其间的任何内容。由于这会进入新范围,因此会为指针对象vowelA
本身分配内存,但不会执行其初始化,因此vowelA
具有不确定的值。
return vowelStore;
vowelStore
是一个局部数组变量。在这种情况下,它被“转换”为指向数组初始元素的指针,相当于&vowelStore[0]
。从函数返回时,数组变量不再存在,因此返回的值是悬空指针。
您应该了解如何在编译器中启用更多警告;它应该能够警告你至少一些这些问题。