我很抱歉这个愚蠢的问题,但我是C和指针的新手。
我写了一个简单的程序,找到一组整数的最大值:
#include <stdio.h>
#define MAX 10
int* getIntegers() {
int a[MAX];
int i = 0;
while (i < MAX) {
int n;
printf("Insert an integer: ");
scanf("%d", &n);
a[i] = n;
i++;
}
int *p = a;
return p;
}
int findMax(int *s) {
int max = -1000000;
for (int i = 0; i < MAX; i++) {
if (s[i] > max) {
max = s[i];
}
}
return max;
}
int main() {
int *p = getIntegers();
int max = findMax(p);
printf("Max value: %d\n", max);
return 0;
}
这个程序似乎有效,但是如果我将MAX
的值从10更改为另一个数字它会停止工作,它会返回另一个我没有作为输入传递的大值。问题似乎是当我调用函数findMax(int *array)
时,因为如果我打印函数getIntegers()
创建的数组,一切似乎都没问题。有谁能够帮我?
答案 0 :(得分:2)
这是因为数组a(在getIntegers中定义)是在堆栈上分配的,因此它意味着你将地址返回到堆栈上已分配的内存。
一旦你的函数getIntegers完成,内存是空闲的,你指向无效的内存。
答案 1 :(得分:2)
根据C标准(6.2.4对象的存储持续时间)相对于具有自动存储持续时间的对象
6对于没有可变长度数组类型的对象, 它的生命周期从进入到它所在的区块延伸 关联,直到该块的执行以任何方式结束
在此功能中
tr td:hover {bg-color:; color:;} /** Highlights row**/
数组int* getIntegers() {
int a[MAX];
// ...
int *p = a;
return p;
}
具有自动存储持续时间,退出函数后其生命周期结束。因此指针a
将具有无效值,因此程序具有未定义的行为。
考虑到程序中存在拼写错误。声明的函数名称为p
,但在main中使用了另一个名称getIntegers
。
getTenIntegers
您需要动态分配所需大小的数组,并在程序结束时释放它。
当函数int main() {
int *p = getTenIntegers();
//...
不依赖于魔法值findMax
时,效果会更好。所以你应该传递给函数第二个值 - 数组的大小。名称MAX也可以是宏名称,因此最好使用其他名称而不是MAX
。
在C函数中,没有参数的main应声明为
MAX
此处显示程序的外观
int main( void )
其输出可能是
#include <stdlib.h>
#include <stdio.h>
#define SIZE 10
int * getIntegers( size_t n )
{
int *a = malloc( n * sizeof( int ) );
if ( a )
{
for ( size_t i = 0; i < n; i++ )
{
int value;
printf( "Insert an integer: " );
scanf( "%d", &value );
a[i] = value;
}
}
return a;
}
size_t findMax( const int *a, size_t n )
{
size_t max = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( a[max] < a[i] ) max = i;
}
return max;
}
int main( void )
{
int *p = getIntegers( SIZE );
if ( p )
{
printf( "Max value: %d\n", p[ findMax( p, SIZE ) ] );
}
free( p );
return 0;
}