如何在这里复制C语言中指针的值而不是地址?

问题描述 投票:0回答:1

我想把 names[j] 投入 namediddle() 函数。我试了几样东西,要么是在 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]);
    }       
}
c pointers
1个回答
1
投票

如果你有一个像这样声明的数组

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];
© www.soinside.com 2019 - 2024. All rights reserved.