我在下面的代码中有一个分段错误,但在我将其更改为指向指针之后,它很好。有人能给我任何理由吗?
void memory(int * p, int size) {
try {
p = (int *) malloc(size*sizeof(int));
} catch( exception& e) {
cout<<e.what()<<endl;
}
}
它在主要功能中不起作用
int *p = 0;
memory(p, 10);
for(int i = 0 ; i < 10; i++)
p[i] = i;
然而,它的工作原理如下。
void memory(int ** p, int size) { `//pointer to pointer`
try{
*p = (int *) malloc(size*sizeof(int));
} catch( exception& e) {
cout<<e.what()<<endl;
}
}
int main()
{
int *p = 0;
memory(&p, 10); //get the address of the pointer
for(int i = 0 ; i < 10; i++)
p[i] = i;
for(int i = 0 ; i < 10; i++)
cout<<*(p+i)<<" ";
return 0;
}
答案 0 :(得分:50)
因为您希望从函数中完成的操作中获取指针值 back 。 malloc
分配内存并为您提供该内存的地址。
在您的第一个示例中,您将该地址存储在本地参数变量p
中,但由于它只是参数,因此不会将其返回到主程序,因为C / C ++是默认情况下按值传递 - 即使是指针。
Main Function malloc
p p allocated
+---+ +---+
| 0 | | 0 | A
+---+ +---+
becomes...
p p allocated
+---+ +---+
| 0 | | ------------> A
+---+ +---+
因此当主读取p时,它变为0,而不是A.
在您的工作代码中,您遵循传递给地址的指针,该地址为您提供主程序中指针变量的位置。您更新该地址的指针值,然后主程序可以查找要用作其内存位置的值 - 从而将malloc
返回的地址传递回主程序以供使用。
Main Function malloc
p p allocated
+---+ +---+
| 0 |<------- | A
| | | |
+---+ +---+
becomes...
p p allocated
+---+ +---+
| |<------- |
| ----------------------> A
+---+ +---+
因此当主读取p时,它得到A。
答案 1 :(得分:7)
指针存储数据存储的地址。将指针传递给函数意味着为其提供数据的地址。但是,在调用malloc
之前,您没有数据地址。因此,您需要传递指针的地址(即指向指针的指针)。这允许memory
获取指针p
的地址,并将p
设置为指向它为数据分配的内存区域。
答案 2 :(得分:3)
在C中,您只有按值传递。所以你的函数memory()得到它自己的p本地副本。内存中的malloc()仅将分配给函数本地的p的副本。当memory()返回main()时,main的p副本不变。在C ++中,您可以使用pass-by-reference来解决此问题,如下所示:
void memory(int*& p, int size)
在C中,您使用双指针来获得类似的结果。
答案 3 :(得分:2)
在你第一次打电话给记忆时:
void memory(int * p, int size)
意识到您将 VALUE 传递给memory(),而不是地址。因此,您将值'0'传递给memory()。变量p
只是您传入的内容的副本... in包含相同的值,但 NOT 指向同一地址...
在你的第二个函数中,你传递了你的论点的 ADDRESS ...所以相反,p
指向变量的地址,而不仅仅是你的副本变量。
所以,当你像这样调用malloc时:
*p = (int *) malloc(size*sizeof(int));
您正在将malloc的返回值分配给p
指向的变量的值。
因此,您的指针在内存()之外有效。
答案 4 :(得分:1)
第一个例子不起作用,因为指针参数不是main中的指针,它只是保持相同的值。
答案 5 :(得分:0)
你不需要使用指向指针的指针,但是引用的指针即*和&amp;不只是*
答案 6 :(得分:0)
您需要指向指针的指针,因为您需要返回新分配的指针的值。
有三种方法可以返回该值(如果使用C,则有2种方法):
第三种方式绝对是我的偏好。
(不是,我不会承认你也可以使用全球,这不是第四种方式,而是恐怖)。
答案 7 :(得分:0)
这只是发送p值而不是p的地址。它发送(* p)。如果p 123的addrees及其值50,则向函数发送50。
并且在记忆功能中它使用新地址(如124)创建一个新指针,它包含50;并且它将分配内存并将分配的内存的开始写入124而不是123,因此主要的p仍然包含50.所以你什么都没做!您可以使用此代码控制此操作。
#include<iostream>
#include<conio.h>
#include<exception>
using namespace std;
void memory(int* p, int size) { //*************pointer to pointer` is a must**********
try{
p = new int[size] ;
p[0]=100;
} catch(bad_alloc &e) {
cout<<e.what()<<endl;
}
}
int main()
{
int *p = 0; ******you can do you should do this*******
p = new int ;
/* p = malloc( sizeof(int)); // this just change the value inside of p it is unnecessary
and you will lose a adress from memory :) and possibly it will be unsafe if you free p may, you just
free one adress*/
/*before using a pointer always allocate it memory else
you ll get frequent system crashes and BSODs*/
memory(p, 10); //get the address of the pointer//you are getting nothing
cout <<p[0];
//we set p[0] to 100 but it will write a garbage value here.
//because the value inside of p didn't change at the memory function
//we sent just the value inside of p.
getch();
return 0;
}
答案 8 :(得分:-1)
我更正了代码..阅读评论,一切都将清楚..
#include<iostream>
#include<conio.h>
#include<exception>
using namespace std;
void memory(int* p, int size) { //pointer to pointer` not needed
try{
p = new int[size] ;
} catch(bad_alloc &e) {
cout<<e.what()<<endl;
}
}
int main()
{
// int *p = 0; wrong .. no memory assigned and then u are passing it to a function
int *p;
p = new int ; // p = malloc( sizeof(int));
/*before using a pointer always allocate it memory else
you ll get frequent system crashes and BSODs*/
memory(p, 10); //get the address of the pointer
for(int i = 0 ; i < 10; i++)
p[i] = i;
for(int i = 0 ; i < 10; i++)
cout<<*(p+i)<<" ";
getch();
return 0;
}