所以代码我写的(大学)应该做以下 - 从用户扫描两个指针动态大小的数组及其大小,然后将它们发送到一个函数(数组作为指针,大小为整数)以及另一个指向整数的指针,该整数将用于确定新数组的大小。 该函数扫描数组A中但不在数组B中的数字,并将这些数字放在一个新数组中,这也是动态的,它的大小由我们提到的指针决定。 然后该函数返回新数组的地址。
就目前而言,我已经做了一切,直到我试图在功能内打印新阵列或者在我返回它的地址之后。 在第一种情况下,它似乎打印各种垃圾,直到程序崩溃,在第二种情况下,它打印一些随机数(可能是一个地址?)。
我希望我尽可能清楚地描述它(考虑到文本的墙),我不是母语,并且在编程方面没有使用英语。
帮助将受到高度赞赏!
代码 -
int *symmetricDiff(int *A, int sizeA, int *B, int sizeB, int *pNewSize) {
int i, j, k = 0, cnt = 0;
int *newArr = (int*)malloc(sizeof(int));
for (i = 0; i < sizeA; i++) {
for (j = 0; j < sizeB; j++) {
if (A[i] == B[j]) {
cnt++;
}
}
if (cnt == 0) {
(*pNewSize)++;
newArr = (int*)realloc(newArr, (*pNewSize + 1) * sizeof(int));
if (newArr == NULL) {
printf("Failed to allocate memory");
return 0;
}
*(newArr+k) = *(A+i);
k++;
}
}
printf("The new array's size is %d\n", *pNewSize);
for (i = 0; i < pNewSize; i++) {
printf("The new array is %d\n", *(newArr + i));
}
return &newArr;
}
int main() {
int numcase, sizeA, sizeB, *pNewSize = 0, i, *A, *B;
while (1) {
printf("Pick a function to activate\n 1 - First paragraph\n 2 - Second paragraph\n 3 - Third paragraph\n 0 - Terminate the application\n\n");
scanf("%d", &numcase);
switch (numcase) {
case 0:
return 0;
printf("\n\n");
break;
case 1:
printf("Enter a size for the first array\n");
scanf("%d", &sizeA);
A = (int*)malloc(sizeA * sizeof(int));
if (A == NULL) {
printf("Failed to allocate memory");
return;
}
for (i = 0; i < sizeA; i++) {
printf("Enter a number for the first array\n");
scanf("%d", &A[i]);
}
printf("Enter a size for the second array\n");
scanf("%d", &sizeB);
B = (int*)malloc(sizeB * sizeof(int));
if (B == NULL) {
printf("Failed to allocate memory");
return;
}
for (i = 0; i < sizeB; i++) {
printf("Enter a number for the second array\n");
scanf("%d", &B[i]);
}
printf("check\n");
symmetricDiff(A, sizeA, B, sizeB, &pNewSize);
/* for (i = 0; i < pNewSize; i++);
printf("The new array is %d\n", **(symmetricDiff));*/
printf("spcheck\n");
printf("\n\n");
free(A);
free(B);
break;
default:
printf("Incorrent input\n");
printf("\n\n");
break;
}
}
}
答案 0 :(得分:3)
你的功能结束:
uvcvideo
这里有两个错误。第一个是printf("The new array's size is %d\n", *pNewSize);
for (i = 0; i < pNewSize; i++) {
printf("The new array is %d\n", *(newArr + i));
}
return &newArr;
是一个指针,需要在pNewSize
循环中取消引用:
for
第二个,如评论中所提到的,for (i = 0; i < *pNewSize; i++) {
已经是一个指针,准备像这样返回:
newArr
此外,在return newArr;
,
main()
应该是
int numcase, sizeA, sizeB, *pNewSize = 0, i, *A, *B;
并通过函数调用中的地址传递:
int numcase, sizeA, sizeB, newSize = 0, i, *A, *B;
答案 1 :(得分:2)
不确定这个小位是否正确,因为你说你想要移动不同的值,所以如果我理解正确的话应该是if (cnt == 0) {
(*pNewSize)++;
newArr = (int*)realloc(newArr, (*pNewSize + 1) * sizeof(int));
if (newArr == NULL) {
printf("Failed to allocate memory");
return 0;
}
*(newArr+k) = *(A+i);
k++;
}
。
return &newArr;
但是,既然你对你的代码充满信心,除了打印,&#34;我已经完成了所有工作,直到我试图在函数内部打印新数组或者在我返回它的地址后&#34; #34;
但是,正如@kaylum所提到的,你将返回一个指向return newArr;
指针的指针,你应该只做int * returnArr = symmetricDiff(A, sizeA, B, sizeB, &pNewSize);
for(i = 0; i < *pNewSize; i++){
printf("%d ",returnArr[i]);
}
。然后要打印它,您需要取消引用返回值。但是,由于这实际上是一个数组,而不仅仅是一个值,您需要遍历数组中的所有值并打印它们,但要执行此操作,您需要捕获返回值。 I.E.
printf("The new array is %d\n", *(symmetricDiff));
上面的代码应该是主要的。
您的注释打印*pNewSize
正在打印指向函数symmetricDiff的解除引用指针。
最后,当您声明{{1}}时,请勿将其设置为零。您实际上是将变量的地址设置为0。
答案 2 :(得分:2)
保持您对symmetricDiff()的原始设计 我看到你回来的最大问题 您当地变量的地址&#39; newArr&#39;而不是价值。
我建议抛光堆栈与堆存储的心智模型 绘制各种指针和存储的图表。 注意:使用铅笔和铅笔更容易做到这一点。纸: - )
我在您的代码中添加了相当多的打印语句,以帮助显示变量发生的情况。
我还添加了一个测试钩子 - 参见选项#9(它只是为A和B分配一些硬连线值,因为每次运行程序时我都不想做数据输入。)
我对打印声明的目标是让您了解如何在不同的地方打印值和地址,并查看代码实际上在做什么(因为我不得不承认,代码并不常见。总是做我们认为正在做的事情:-))。
浏览实际输出(下面,第一个)并根据修改后的源代码(下面,第二个)引用它。
检查变量的值(及其地址),看看是否有助于解开原始代码。
祝你好运,编码愉快: - )
P.S。我的道歉是相当冗长的,我为此做了道歉 - 我希望尽可能简化调试添加,并且不需要在结构中包装东西或类似的东西&#34; printf&#34;是要走的路。
这里的takehome消息将是1)记住你可以添加足够的打印件以显示正在发生的任何事情,以及2)一旦你绕过地址和指针,你就不会像疯了一样我在这里做了。
$ ./a.out
-----
Pick a function to activate
1 - First paragraph
2 - Second paragraph
3 - Third paragraph
9 - test
0 - Terminate the application
9
You entered 9...
main(): testing. Before we initialze too much, lets see what is going on with our local vars...
Testing... just for illustration let's print out the address of our local vars:
type varname value address sizeof
------ ------- ---------- ----------------- ----------------
int numcase = 9 &numcase= BC7A898 sizeof( numcase )=4
int sizeA = 0 &sizeA= BC7A894 sizeof( sizeA )=4
int* A = 4012A0 &A= BC7A888 sizeof( A )=8
int sizeB = 52 &sizeB= BC7A884 sizeof( sizeB )=4
int* B = 4012E5 &sizeB= BC7A878 sizeof( B )=8
int sizeDiff = 32766 &sizeDiff= BC7A874 sizeof( sizeDiff )=4
int* Diff = 40051B &Diff= BC7A868 sizeof( Diff )=8
main(): numcase should be 9 becuase we chose the 'test' option.
: sizeA and sizeB aren't yet initialized.
: Also A, B, and Diff don't point to known values (they are
: are not valid heap addresses yet because we haven't assigned them).
: Just for fun, notice on the far right that our integers are all 4 bytes (32 bit)
: while the pointers are all 8 bytes (64 bits).
main():Before symmetricDiff()... (skipping addresses and sizeofs for local vars, no changes there)
type varname value
------ ------- ----------
int numcase = 9
int sizeA = 4
int* A = A25010
int sizeB = 3
int* B = A25030
int sizeDiff = 32766
int* Diff = 40051B
main():numcase should still be 9.
:sizeA and sizeB should now be 4 and 3 respectively.
:A and B should point to something on our heap - thanks, malloc().
:sizeDiff and Diff should still be the same (e.g. uninitialized).
symmetricDiff(): Very beginning. Before we initialze too much, lets see what is going on with our params and local vars...
type varname value address sizes
------ ------- ---------- ----------------- ----------------
int sizeA = 4 &sizeA= BC7A814 sizeof( sizeA )=4
int* A = A25010 &A= BC7A818 sizeof( A )=8
int sizeB = 3 &sizeB= BC7A804 sizeof( sizeB )=4
int* B = A25030 &B= BC7A808 sizeof( B )=8
int i = 52 &i= BC7A83C sizeof( i )=4
int j = -943289501 &j= BC7A838 sizeof( j )=4
int cnt = 0 &cnt= BC7A834 sizeof( cnt )=4
int* newArr = 47 &newArr= BC7A828 sizeof( newArr )=8
int* pNewSize = BC7A874 &pNewSize= BC7A7F8 sizeof(pNewSize )=8
symmetricDiff(): notice that sizeA, sizeB, A and B have the same values here but different addresses.
: IMPORTANT - note that the values of main's A and our A (here in symmetricDiff) are the same,
: but the ADDRESSES of main's A and symmetricDiff's A are different.
: Also note that the VALUE of symmetricDiff's pNewSize matches the ADDRESS of main's sizeDiff.
: Except for cnt, our local vars i, j, and newArr have more or less random values becuase they're
: not yet initialized.
symmetricDiff(): looping, i=0
int cnt = 0
int* newArr = 10637392
symmetricDiff(): i will change. j should be last value assigned (dont really care about that).
: Also no change for sizeA, A, sizeB, B.
: cnt may change, if so the value (heap location) of newArray may be changed because of realloc().
symmetricDiff(): looping, i=1
int cnt = 0
int* newArr = 10637392
symmetricDiff(): i will change. j should be last value assigned (dont really care about that).
: Also no change for sizeA, A, sizeB, B.
: cnt may change, if so the value (heap location) of newArray may be changed because of realloc().
symmetricDiff(): looping, i=2
int cnt = 1
int* newArr = 10637392
symmetricDiff(): i will change. j should be last value assigned (dont really care about that).
: Also no change for sizeA, A, sizeB, B.
: cnt may change, if so the value (heap location) of newArray may be changed because of realloc().
symmetricDiff(): looping, i=3
int cnt = 2
int* newArr = 10637392
symmetricDiff(): i will change. j should be last value assigned (dont really care about that).
: Also no change for sizeA, A, sizeB, B.
: cnt may change, if so the value (heap location) of newArray may be changed because of realloc().
The new array's size is 2
newArr[0]=101
newArr[1]=102
symmetricDiff(): Ready to return, will return newArr's value (A25050) to caller.
type varname value
------ ------- ----------
int sizeA = 4
int* A = A25010
int sizeB = 3
int* B = A25030
int i = 2
int j = 3
int cnt = 2
int* newArr = A25050
int* pNewSize = BC7A874
symmetricDiff(): no changes for values of sizeA, sizeB, A and B.
: i and j and cnt did change from beginning.
: pNewSize *looks* like id didn't change, it still has the same value.
: But what pNewSize *points* to did change.
: Now *pNewSize=2 which should be the same as 'cnt'
main():After symmetricDiff()...
type varname value
------ ------- ----------
int numcase = 9
int sizeA = 4
int* A = A25010
int sizeB = 3
int* B = A25030
int sizeDiff = 2
int* Diff = A25050
main():No change for numcase, sizeA, sizeB, A, and B
:sizeDiff and Diff reflect what symmetricDiff() did.
:Now that Diff is pointing to the new 'array' in heap storage
:Thank you, symmetricDiff, now we can safely print the array.
------------------
main(): The new array's size is 2
Diff[0]=101
Diff[1]=102
-----
Pick a function to activate
1 - First paragraph
2 - Second paragraph
3 - Third paragraph
9 - test
0 - Terminate the application
0
You entered 0...
$
#include <stdio.h>
#include <stdlib.h>
/*
* I added some code to print pointer values and addresses... to make alingment
* work better I'm using %10d for all memory locations as well as normal integers.
* In my own code I tend to use %X for memory locations, but it makes it harder to
* keep things alinged and I felt the visual benefit of slightly easier reading
* was worth not using hex for addresses.
*/
int *symmetricDiff(int *A, int sizeA
, int *B, int sizeB
, int *pNewSize ) {
int i;
int j;
int cnt = 0;
/* int IGNORE_k = 0; */
/* I changed 'k' to IGNORE_k because 'cnt' is sufficient. */
int *newArr; /* left uninitialized just to show beofre & after values. */
printf("\nsymmetricDiff(): Very beginning. Before we initialze too much, lets see what is going on with our params and local vars...\n");
printf("type varname %10s address%10s sizes\n", "value", "" );
printf("------ ------- %10s -------%10s ----------------\n", "----------", "----------" );
printf("int sizeA = %10d &sizeA=%10X sizeof( sizeA )=%d\n", sizeA, &sizeA, sizeof(sizeA) );
printf("int* A = %10X &A=%10X sizeof( A )=%d\n", A, &A, sizeof(A) );
printf("int sizeB = %10d &sizeB=%10X sizeof( sizeB )=%d\n", sizeB, &sizeB, sizeof(sizeB) );
printf("int* B = %10X &B=%10X sizeof( B )=%d\n", B, &B, sizeof(B) );
printf("int i = %10d &i=%10X sizeof( i )=%d\n", i, &i, sizeof(i) );
printf("int j = %10d &j=%10X sizeof( j )=%d\n", j, &j, sizeof(j) );
printf("int cnt = %10d &cnt=%10X sizeof( cnt )=%d\n", cnt, &cnt, sizeof(cnt) );
printf("int* newArr = %10X &newArr=%10X sizeof( newArr )=%d\n", newArr, &newArr, sizeof(newArr) );
printf("int* pNewSize = %10X &pNewSize=%10X sizeof(pNewSize )=%d\n", pNewSize, &pNewSize, sizeof(pNewSize) );
printf("symmetricDiff(): notice that sizeA, sizeB, A and B have the same values here but different addresses.\n");
printf(" : IMPORTANT - note that the values of main's A and our A (here in symmetricDiff) are the same,\n");
printf(" : but the ADDRESSES of main's A and symmetricDiff's A are different.\n");
printf(" : Also note that the VALUE of symmetricDiff's pNewSize matches the ADDRESS of main's sizeDiff.\n");
printf(" : Except for cnt, our local vars i, j, and newArr have more or less random values becuase they're\n");
printf(" : not yet initialized.\n");
newArr = (int*)malloc(sizeof(int));
for (i = 0; i < sizeA; i++) {
printf("\nsymmetricDiff(): looping, i=%d\n", i);
printf("int cnt = %10d\n", cnt );
printf("int* newArr = %10d\n", newArr );
printf("symmetricDiff(): i will change. j should be last value assigned (dont really care about that).\n");
printf(" : Also no change for sizeA, A, sizeB, B.\n");
printf(" : cnt may change, if so the value (heap location) of newArray may be changed because of realloc().\n");
for (j = 0; j < sizeB; j++) {
if( A[i] == B[j] ) {
newArr[cnt] = A[i];
cnt++;
/* Let's wait to tell our caller about what happened until just before we return.
* We can just use local var 'cnt' for now...
* (*pNewSize)++;
* newArr = (int*)realloc(newArr, (*pNewSize + 1) * sizeof(int));
* After all we did increment 'cnt' just above here.
*/
newArr = (int*)realloc(newArr, cnt * sizeof(int));
if (newArr == NULL) {
printf("Failed to allocate memory");
/* return 0; /* using NULL instead of 0 probalby better style here. */
return NULL;
}
}
}
}
/* print out what we found. */
/* We'll use 'cnt' here... caller can use whatever pNewSize points to.
* OLD: printf("The new array's size is %d\n", *pNewSize);
* OLD: for (i = 0; i < pNewSize; i++) {
* OLD: printf("The new array is %d\n", *(newArr + i));
* OLD: }
*/
printf("\nThe new array's size is %d\n", cnt );
for (i = 0; i < cnt; i++) {
printf("newArr[%d]=%d\n", i, newArr[i] );
/* Or if you prefer:
* printf("newArr[%d]=%d\n", i, *(newArr+i) );
* newArr[i] is just a short hand expression for *(newArr+i)
*/
}
/* Now that we are done with all the work let's tell our caller what we found. */
*pNewSize = cnt;
/* DANGER: this way we were returning the ADDRESS of our local pointer "newArr".
* return &newArr;
* The address you want to return is whatever was last allocated (malloc or realloc)
* on the heap, which is the value of newArr.
*/
printf("\nsymmetricDiff(): Ready to return, will return newArr's value (%X) to caller.\n", newArr);
printf("type varname %10s\n", "value" );
printf("------ ------- %10s\n", "----------" );
printf("int sizeA = %10d\n", sizeA );
printf("int* A = %10X\n", A );
printf("int sizeB = %10d\n", sizeB );
printf("int* B = %10X\n", B );
printf("int i = %10d\n", i );
printf("int j = %10d\n", j );
printf("int cnt = %10d\n", cnt );
printf("int* newArr = %10X\n", newArr );
printf("int* pNewSize = %10X\n", pNewSize );
printf("symmetricDiff(): no changes for values of sizeA, sizeB, A and B.\n");
printf(" : i and j and cnt did change from beginning.\n");
printf(" : pNewSize *looks* like id didn't change, it still has the same value.\n");
printf(" : But what pNewSize *points* to did change.\n");
printf(" : Now *pNewSize=%d which should be the same as 'cnt'\n", *pNewSize );
return newArr;
/* To elaborate, the original code was returning the ADDRESS of local variable 'newArr'
* which is a problem because that address is going to evaporate the instant we
* return from the function (e.g. stack storage goes away; strictly speaking it won't evaporate
* but it will be IMMEDIATELY recycled and have a other values stored in it, and those other values
* are almost never going to have anything to do wiht what 'newArr' was pointing to on the heap.
*/
}
int main() {
int numcase;
int sizeA;
int *A;
int sizeB;
int *B;
/* int *IGNORE_pNewSize = 0; newSize should be an actual integer, not a pointer to an integer */
int sizeDiff; /* name change to match sizeA convention. we wil pass the address of this int to symmetricDiff. */
int *Diff;
int i;
while (1) {
printf("\n-----\nPick a function to activate\n");
printf("1 - First paragraph\n");
printf("2 - Second paragraph\n");
printf("3 - Third paragraph\n");
printf("9 - test\n"); /* NEW: added to simplify testing. */
printf("0 - Terminate the application\n");
scanf("%d", &numcase);
printf("You entered %d...\n", numcase );
switch (numcase) {
case 0:
return 0;
printf("\n\n");
break;
case 1:
printf("Enter a size for the first array\n");
scanf("%d", &sizeA);
A = (int*)malloc(sizeA * sizeof(int));
if (A == NULL) {
printf("Failed to allocate memory");
return;
}
for (i = 0; i < sizeA; i++) {
printf("Enter a number for the first array\n");
scanf("%d", &A[i]);
}
printf("Enter a size for the second array\n");
scanf("%d", &sizeB);
B = (int*)malloc(sizeB * sizeof(int));
if (B == NULL) {
printf("Failed to allocate memory");
return;
}
for (i = 0; i < sizeB; i++) {
printf("Enter a number for the second array\n");
scanf("%d", &B[i]);
}
printf("check\n");
/* fix me: symmetricDiff(A, sizeA, B, sizeB, &pNewSize); */
/* for (i = 0; i < pNewSize; i++);
printf("The new array is %d\n", **(symmetricDiff));*/
printf("spcheck\n");
printf("\n\n");
free(A);
free(B);
break;
case 9: /* NEW: added to simplify testing. */
printf("\nmain(): testing. Before we initialze too much, lets see what is going on with our local vars...\n");
printf("Testing... just for illustration let's print out the address of our local vars:\n");
printf("type varname %10s address%10s sizeof\n", "value", "" );
printf("------ ------- %10s -------%10s ----------------\n", "----------", "----------" );
printf("int numcase = %10d &numcase=%10X sizeof( numcase )=%d\n", numcase, &numcase, sizeof(numcase) );
printf("int sizeA = %10d &sizeA=%10X sizeof( sizeA )=%d\n", sizeA, &sizeA, sizeof(sizeA) );
printf("int* A = %10X &A=%10X sizeof( A )=%d\n", A, &A, sizeof(A) );
printf("int sizeB = %10d &sizeB=%10X sizeof( sizeB )=%d\n", sizeB, &sizeB, sizeof(sizeB) );
printf("int* B = %10X &sizeB=%10X sizeof( B )=%d\n", B, &B, sizeof(B) );
printf("int sizeDiff = %10d &sizeDiff=%10X sizeof( sizeDiff )=%d\n", sizeDiff, &sizeDiff, sizeof(sizeDiff) );
printf("int* Diff = %10X &Diff=%10X sizeof( Diff )=%d\n", Diff, &Diff, sizeof(Diff) );
printf("main(): numcase should be 9 becuase we chose the 'test' option.\n");
printf(" : sizeA and sizeB aren't yet initialized.\n");
printf(" : Also A, B, and Diff don't point to known values (they are\n");
printf(" : are not valid heap addresses yet because we haven't assigned them).\n");
printf(" : Just for fun, notice on the far right that our integers are all 4 bytes (32 bit)\n");
printf(" : while the pointers are all 8 bytes (64 bits).\n");
printf("\n");
sizeA = 4; A = (int*)malloc(sizeA * sizeof(int));
sizeB = 3; B = (int*)malloc(sizeB * sizeof(int));
if (A == NULL || B == NULL) {
printf("Failed to allocate memory");
return;
}
A[0] = 100; A[1] = 101; A[2] = 102; A[3] = 103;
B[0] = 101; B[1] = 102; B[2] = 400;
printf("\nmain():Before symmetricDiff()... (skipping addresses and sizeofs for local vars, no changes there)\n");
printf("type varname %10s\n", "value" );
printf("------ ------- %10s\n", "----------" );
printf("int numcase = %10d\n", numcase );
printf("int sizeA = %10d\n", sizeA );
printf("int* A = %10X\n", A );
printf("int sizeB = %10d\n", sizeB );
printf("int* B = %10X\n", B );
printf("int sizeDiff = %10d\n", sizeDiff );
printf("int* Diff = %10X\n", Diff );
printf("main():numcase should still be 9.\n");
printf(" :sizeA and sizeB should now be 4 and 3 respectively.\n");
printf(" :A and B should point to something on our heap - thanks, malloc().\n");
printf(" :sizeDiff and Diff should still be the same (e.g. uninitialized).\n");
Diff = symmetricDiff(
A, sizeA,
B, sizeB,
&sizeDiff );
printf("\nmain():After symmetricDiff()...\n");
printf("type varname %10s\n", "value" );
printf("------ ------- %10s\n", "----------" );
printf("int numcase = %10d\n", numcase );
printf("int sizeA = %10d\n", sizeA );
printf("int* A = %10X\n", A );
printf("int sizeB = %10d\n", sizeB );
printf("int* B = %10X\n", B );
printf("int sizeDiff = %10d\n", sizeDiff );
printf("int* Diff = %10X\n", Diff );
printf("main():No change for numcase, sizeA, sizeB, A, and B\n");
printf(" :sizeDiff and Diff reflect what symmetricDiff() did.\n");
printf(" :Now that Diff is pointing to the new 'array' in heap storage\n");
printf(" :Thank you, symmetricDiff, now we can safely print the array.");
printf("\n------------------\n");
printf("main(): The new array's size is %d\n", sizeDiff);
for (i = 0; i < sizeDiff; i++) {
printf(" Diff[%d]=%d\n", i, Diff[i] );
}
break;
default:
printf("Incorrent input\n");
printf("\n\n");
break;
}
/* WARNING: if you're going to run this in a loop you should
* probably free the heap storage owned by A, B, and Diff.
* Otherwise the next time through the loop will leak memory.
* Before doing that, go ahead and run '9' a few times and
* see if the memory locations stay the same for A, B, and Diff.
* free( A );
* free( B );
* free( Diff );
*/
}
}