函数调用后,参数指针不保留其值
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
的值].
如果要更改 main
中 K1ptr
的值,您需要将指向 K1ptr
的 指针传递给函数。但是,当您将 K1ptr
初始化为指向字符数组 K1[9]
时,这似乎有点奇怪。我的猜测是您不想更改函数中的指针值,而只是将一些数据复制到 "pointed-to" 数组中。
顺便说一句:
你的P8_swap
是错误的。您 return 指向 P8_Output
的指针,这是一个局部变量。永远不要那样做!当函数 returns 时,局部变量超出范围(也就是不再存在),因此 returned 指针指向非法内存。如果你真的想要那样的东西,你必须使用动态内存分配。
函数参数定义K1
和K2
:
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.
我正在将 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
的值].
如果要更改 main
中 K1ptr
的值,您需要将指向 K1ptr
的 指针传递给函数。但是,当您将 K1ptr
初始化为指向字符数组 K1[9]
时,这似乎有点奇怪。我的猜测是您不想更改函数中的指针值,而只是将一些数据复制到 "pointed-to" 数组中。
顺便说一句:
你的P8_swap
是错误的。您 return 指向 P8_Output
的指针,这是一个局部变量。永远不要那样做!当函数 returns 时,局部变量超出范围(也就是不再存在),因此 returned 指针指向非法内存。如果你真的想要那样的东西,你必须使用动态内存分配。
函数参数定义K1
和K2
:
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.