我想把 names[j]
投入 name
在 diddle()
函数。我试了几样东西,要么是在 name
反映的是 name[j]
到 "0"
当我归还它,或者我得到一个segfault。我错过了什么?
randomGenerator
返回一个整数,对应于 names[]
.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
char* names[9];
//char* diddle(char *names[]) {
void diddle(char *names[], char *name) {
int i;
while (1) {
int j = randomGenerator(0,9);
printf("j is %d\n",j);
int x;
x = strcmp(names[j],"0");
printf("names[j] is %s and x is %d\n",names[j],x);
if (x != 0) {
strcpy(name,names[j]);
strcpy(names[j],"0");
break;
}
}
//return name;
}
int main() {
names[0] = (char *) malloc(4 * sizeof(char*));
strcpy(names[0],"foo");
names[1] = (char *) malloc(4 * sizeof(char*));
strcpy(names[1],"bar");
names[2] = (char *) malloc(4 * sizeof(char*));
strcpy(names[2],"baz");
names[3] = (char *) malloc(4 * sizeof(char*));
strcpy(names[3],"qux");
names[4] = (char *) malloc(4 * sizeof(char*));
strcpy(names[4],"zed");
names[5] = (char *) malloc(4 * sizeof(char*));
strcpy(names[5],"pug");
names[6] = (char *) malloc(4 * sizeof(char*));
strcpy(names[6],"unk");
names[7] = (char *) malloc(4 * sizeof(char*));
strcpy(names[7],"fed");
names[8] = (char *) malloc(4 * sizeof(char*));
strcpy(names[8],"hip");
names[9] = (char *) malloc(4 * sizeof(char*));
strcpy(names[9],"gib");
int i;
for(i = 0; i < 7; i++) {
//char *name = diddle(&names[0]);
char *name = NULL;
diddle(&names[0],&name);
printf("main loop: name is %s\n", name);
}
for (i = 0; i < 10; i++) {
free(names[i]);
}
}
如果你有一个像这样声明的数组
char* names[9];
那么这个数组的有效指数范围是 [0, 9)
.
因此,这些声明
names[9] = (char *) malloc(4 * sizeof(char*));
strcpy(names[9],"gib");
访问不存在的数组元素,但索引无效。9
.
这个循环
for (i = 0; i < 10; i++) {
free(names[i]);
}
同样的原因也是不正确的。
不要使用像9 0r 10这样的神奇数字。使用命名的常数,例如
enum { N = 9 };
char* names[N];
//...
for (i = 0; i < N; i++) {
free(names[i]);
}
而且声明数组 names
作为一个全局变量。你可以在main中声明它。
虽然分配的内存
names[0] = (char *) malloc(4 * sizeof(char*));
可容纳一串四个字符
strcpy(names[0],"foo");
然而这样的分配只会让代码的读者感到困惑。相反,在这个语句中写上其他类似的语句
names[0] = (char *) malloc(4 * sizeof(char));
^^^^^
或者只是
names[0] = (char *) malloc( 4 );
职能 diddle
第二个参数的类型是 char *
void diddle(char *names[], char *name) {
但在函数调用中
diddle(&names[0],&name);
有句话叫 &name
属于 char **
.
因此,本声明
strcpy(name,names[j]);
调用未定义的行为。即使传递的表达式具有正确的类型
diddle(&names[0],&name);
但该函数又有未定义的行为,因为传递的指针是一个空指针。所以你不能使用 strcpy
的空指针。
而不是空指针
char *name = NULL;
你可以使用一个字符数组,比如
char name[4];