指向 c 中结构的指针
Posted
技术标签:
【中文标题】指向 c 中结构的指针【英文标题】:Pointer to Pointer to a structure in c 【发布时间】:2014-10-02 14:41:33 【问题描述】:我有一个简单的结构。
struct grades
int lowest;
int highest;
;
然后我要创建一个函数,该函数返回一个初始化结构的指针。
struct *grades setGrades(int low, int high)
struct *ptr = malloc(sizeof(struct grades));
ptr->lowest = low;
ptr->highest = high;
return ptr;
现在我应该创建一个定义为struct **grades random(int size);
的函数
我应该为指向grade
结构的指针数组分配空间,其中元素的数量等于size
。创建指针数组时,我想将数组中的每个指针设置为新创建的数据结构,该数据结构的低变量等于 10,高变量等于 100,然后返回指针。
此时我真的很迷茫,因为我在网上查找了指向结构的双指针,但没有找到任何可以帮助我理清理解的示例。我想知道是否有人可以向我解释指向结构的双指针是如何工作的,这将使我在正确的方向上有一个很好的开始。
【问题讨论】:
struct *grades
和 struct *ptr
???
一个更好的函数名应该是createGradeSet
,因为每次调用都会返回一个新结构。
不,但你肯定是指struct grades*
和struct grades* ptr
,不是吗? ;)
我仍然不明白为什么需要指针。如果曾经有一个结构可以轻松地按值复制,那就是它。
“双指针”不太可能给你很多相关的点击。有一个数字类型double
用于“双精度浮点数”(就像浮点数,但“更大”)。您可能会通过“指向指针的指针”找到更多相关的阅读材料。如果您将指针视为与任何其他数据类型一样的数据类型,请意识到 *pp
如果 pp 是指向指针的指针,则会为您提供指针。
【参考方案1】:
您所说的“双指针”只是指向指针的指针。也就是说,struct grade example
是一个变量,包含您定义的 lowest
和 highest
。指向它的指针,struct grade *example
是一个存储同一结构的内存地址的变量。指向指针struct grade **example
的指针是一个存储结构内存地址的变量的内存地址的变量。更详细的解释可以在here 找到。无论如何,要回答您的具体问题,函数将是:
struct grades** random(int size)
struct grades** result = malloc(sizeof(struct grades*) * size); //here you are
//allocating enough space for an
//array of pointers
int i;
for(i = 0; i < size; i++)
result[i] = setGrades(10, 100); //here you are setting each pointer to one
//grade through the function you've already
//defined
return result;
【讨论】:
如何打印双指针设置的值来检查它是否被设置? 对于单个指针,您会打印result->lowest
,对吗?对于指向指针的指针,您需要使用result[i]->lowest
。这里,result[i]
是指向成绩的指针数组中的 i
-th 指针。【参考方案2】:
struct grades int lowest; int highest; ;
struct grades * createGradeSet(int low, int high) //careful: return type is struct grades *
// variable name: ptr, type: struct grades *
struct grades * ptr = malloc(sizeof(struct grades));
ptr->lowest = low;
ptr->highest = high;
return ptr;
struct grades ** random(int size)
// Create a pointer to an array of struct grades pointers
// the size of the array is `size` x the size of a struct grades pointer
struct grades ** ptr_arr = malloc(sizeof(struct grades *) * size);
for (unsigned int i = 0; i < size; i++)
ptr_arr[i] = createGradeSet(10, 100); // assign a newly created Gradeset to every cell
return ptr_arr;
【讨论】:
【参考方案3】:试试下面的
struct grades ** random( size_t size )
if ( size == 0 ) return NULL:
struct grades **p = malloc( size * sizeof( struct grades * ) );
if ( p != NULL )
size_t i = 0;
do
p[i] = malloc( sizeof( struct grades ) );
if ( p[i] != NULL )
p[i]->lowest = 10;
p[i]->highest = 100;
while ( p[i] != NULL && ++i < size );
if ( i != size )
for ( size_t j = 0; j < i; j++ ) free( p[i] );
free( p );
p = NULL;
return p;
函数setGrades应该写成
struct *grades setGrades( int low, int high )
struct *p = malloc( sizeof( struct grades ) );
if ( p != NULL )
p->lowest = low;
p->highest = high;
return p;
在这种情况下,上述函数中的do while循环可以写成
do
p[i] = setGrades( 10, 100 );
while ( p[i] != NULL && ++i < size );
【讨论】:
请注意,检查malloc()
的返回值不能让你的程序不再崩溃:现代内核过度提交它们的内存,所以malloc()
在正常情况下不会返回NULL。程序既不会崩溃也不会有机会意识到没有内存来支持它的分配,当内核意识到它的内存不足时,它会被枪杀。因此,检查malloc()
的返回值远不像以前那样可取。尤其是考虑到它如何使您的代码变得混乱。
不,我不这么认为:内核基本上不可能知道它何时过度使用内存,如果它运行一个保守的策略,实际上几乎不可能使用所有可用的内存.想想分叉的效果:理论上,新进程需要的内存与旧进程所需的内存一样多。因此,在保守的政策下,如果您的进程已经拥有一半的内存,您将无法分叉。但是在由于system()
调用而产生的fork 中,fork 会立即释放继承的内存。所以内核不应该阻止你的进程分叉。
@cmaster 很抱歉,我对这个愚蠢的东西不感兴趣。我建议考虑一下这种情况下的所有 prohrams 都有未定义的行为。:)
在所有健全的系统上都存在段错误的未定义行为......是的,从技术上讲,语言标准允许任何事情发生,但是取消引用 NULL 指针是我所知道的所有系统都拥有的常见事情内置的保护措施可以安全地对执行此操作的任何程序进行安全检测。以上是关于指向 c 中结构的指针的主要内容,如果未能解决你的问题,请参考以下文章