函数调用后,参数指针不保留其值

After function call, argument pointers don't keep their value

我正在将 3 个指针(key、K1Ptr、K2Ptr)作为参数传递给函数 (keyGenerator),但是当函数调用结束时,只有键指针保留函数调用的值,其他 2 个指针不保留t.

我尝试了很多不同的方法,比如返回一个带有 2 个指针的数组,或者我尝试不使用指针而是传递 2 个数组。两次尝试都有相同的结果 none 在函数调用后保持值。

char K1[9], K2[9];
char *K1ptr, *K2ptr;

K1ptr = K1;
K2ptr = K2;

keyGenerator(key, K1ptr, K2ptr);

printf("Key. %s\n", key);
printf("K1. %s\n", K1Ptr);
printf("K2. %s\n", K2Ptr);

\

void keyGenerator(char *key, char *K1, char *K2) {

char P10_Left[6];
char P10_Right[6];
char *P10leftPtr, *P10rightPtr;


printf("Starting key: %s\n", key);

//P10 Operation first step
P10_swap(key);
printf("P10swap key: %s\n", key);

//Initializing the left and right arrays
int i;
for(i=0;i<5;i++) {

    P10_Left[i] = key[i];
    P10_Right[i] = key[i+5];
}
P10_Left[5] = '[=11=]';
P10_Right[5] = '[=11=]';

P10leftPtr = P10_Left;
P10rightPtr = P10_Right;

//The left half shift
LS(P10leftPtr, 1);
//The right half shift
LS(P10rightPtr, 1);


//P8 swap starts here
K1 = P8_swap(P10leftPtr, P10rightPtr);

printf("K1 key: %s\n", K1);
//P8 swap ends here


//After we find K1 we need to shift the 2 halves again, 2 times to the left this time
//The left half shift
LS(P10leftPtr, 2);
//The right half shift
LS(P10rightPtr, 2);


//After the 2 shifts we use P8 operation again on the new halves
//P8 swap starts here
K2 = P8_swap(P10leftPtr, P10rightPtr);

printf("K2 key: %s\n", K2);
//P8 swap ends here

} //

char* P8_swap(char *left_key, char *right_key) {

int P8[8] = {6, 3, 7, 4, 8, 5, 10, 9}; //key possitions after P8 operation
char P8_Output[9];
char *K1; //They key after the P8 swap
char keyLR[11]; //The left and right halves will be stored together here

int i;

//The two halves become one so that we can do the P8 swap
for(i=0;i<5;i++) {
    keyLR[i] = left_key[i];
    keyLR[i+5] = right_key[i];
}

//P8 swap
for(i=0; i<8; i++) {
    P8_Output[i] = keyLR[P8[i]-1];  //P10[i] - 1 because the possitiongs in P10 are from 1-10 and not 0-9
}

P8_Output[8] = '[=12=]';

K1 = P8_Output;

return K1;

}

在函数 keyGenerator 之后,当我打印 K1Ptr 和 K2Ptr 时,我什么也没得到,但我希望得到存储在函数中的值。

这一行:

K1 = P8_swap(P10leftPtr, P10rightPtr);

您更改了 K1 的值,但该更改是 local 函数,不会更改 main 中的 K1ptr 的值].

如果要更改 mainK1ptr 的值,您需要将指向 K1ptr 指针传递给函数。但是,当您将 K1ptr 初始化为指向字符数组 K1[9] 时,这似乎有点奇怪。我的猜测是您不想更改函数中的指针值,而只是将一些数据复制到 "pointed-to" 数组中。

顺便说一句:

你的P8_swap是错误的。您 return 指向 P8_Output 的指针,这是一个局部变量。永远不要那样做!当函数 returns 时,局部变量超出范围(也就是不再存在),因此 returned 指针指向非法内存。如果你真的想要那样的东西,你必须使用动态内存分配。

函数参数定义K1K2:

void keyGenerator(char *key, char *K1, char *K2)

隐藏全局变量:

char K1[9], K2[9];

并且由于函数参数在函数范围内是局部的,因此它们实际上被分配了,但该值不会传播到其他地方定义的变量。

尝试使用:

void keyGenerator(char *key, char **K1, char **K2)

并称它为:

keyGenerator(key, & K1ptr, & K2ptr);

还需要根据 P8_swap 函数更改函数内部对 K1 的赋值。

问题就在这里

K1 = P8_swap(P10leftPtr, P10rightPtr);

这里

K2 = P8_swap(P10leftPtr, P10rightPtr);

您基本上是在覆盖指针的值,以便它们指向最终在函数调用结束时销毁的其他对象。

因此,您需要将 P8_swap() 调用的 return 值复制到指针的内容中,如下所示:

char* tmp = P8_swap(P10leftPtr, P10rightPtr);
memcpy(K1, tmp, strlen(tmp)+1);

...

tmp = P8_swap(P10leftPtr, P10rightPtr);
memcpy(K2, tmp, strlen(tmp)+1);

您可以阅读更多关于 memcpy here

或者一个基本的 for 循环也可以做到这一点

char* tmp = P8_swap(P10leftPtr, P10rightPtr);
for(int i = 0; i < strlen(tmp); i++) {
  K1[i] = tmp[i];
}

编辑:

正如@4386427 刚刚指出的那样,tmp 在这种情况下将是一个不安全的指针,因为 return 值 P8_swap() 可能同时被破坏 - 因为它是在函数中本地定义的。

但是,如果内存是为值动态分配的(在函数内)——正如我最初假设的那样,那么指针可以安全使用。 See demo.