gpt4 book ai didi

c - 使用静态指针的动态内存分配

转载 作者:太空宇宙 更新时间:2023-11-03 23:19:32 24 4
gpt4 key购买 nike

有人可以向我解释一下为什么下面这段代码是这样工作的吗?这里我在文件code2.c 中将outd 初始化为一个静态指针。然后我使用 malloc 动态地为其分配内存。从单独文件 code1.c 中的主函数一次又一次地调用它,它看起来整个数组以静态方式运行,因为它保留了从一个函数调用到另一个函数调用的所有值,即使数组的内存是动态分配的。我期待的是段错误之类的东西。

code2.c

#include <stdio.h>
#include <stdlib.h>

static double *outd;

void init0(int len)
{
int i;
outd=malloc(sizeof(double)*len);
for (i=0; i<len; i++)
{
outd[i]=0.0;
}
}

void showarray(int len, int iterno)
{
int i;
printf("iteration %d, array is \n",iterno);
for (i=0; i<len; i++)
{
outd[i]=outd[i]+iterno;
printf("%.2f ",outd[i]);
}
printf("\n");
}

void deletearray()
{
free(outd);
}

code1.c

#include <stdio.h>
#include <stdlib.h>

void init0(int len);
void showarray(int len, int iterno);
void deletearray();

int main(int argc,char* argv[])
{
int i, len;
len=5;

init0(len);

for (i=0; i<7; i++)
{
showarray(len,i);
}

deletearray();
}

编译,

$(CC) -c -O2 code1.c 
$(CC) -c -O2 code2.c
$(CC) -o bb5 code1.o code2.o -lm

运行

localhost:testfft avinash$ ./bb5
iteration 0, array is
0.00 0.00 0.00 0.00 0.00
iteration 1, array is
1.00 1.00 1.00 1.00 1.00
iteration 2, array is
3.00 3.00 3.00 3.00 3.00
iteration 3, array is
6.00 6.00 6.00 6.00 6.00
iteration 4, array is
10.00 10.00 10.00 10.00 10.00
iteration 5, array is
15.00 15.00 15.00 15.00 15.00
iteration 6, array is
21.00 21.00 21.00 21.00 21.00

最佳答案

请在评论和其他答案中找到技术答案。
我提供代码(基于您的代码)来说明这些很好的解释。

为了实现这一效果,我使用了各种静态变量(两种)、局部变量和全局变量。
(为了简单起见,我使用整数而不是指针。
不同之处在于缓冲区是否已更改,这可能是您的突出困惑的部分答案。有关于发生了什么和没有发生什么的评论。)

code2.c:

#include <stdio.h>
#include <stdlib.h>

// defining a pointer which is only visible from this file,
// to later be initialised to the return value of malloc()
static double *outd;

// defining an int which is only visible from this file,
// to later be initialised to some integer value
static int outI;

// define an int which is only visible from this file,
// but has an identically named twin in the other file
// (there be dragons)
static int unknownTwinI;

// defining a global int which is visible from main()
int globalI;

void init0(int len)
{
int i;

// initialise the pointer
// to the address of a buffer reserved for use via this pointer
outd=malloc(sizeof(double)*len);

// initialise the memory inside that buffer
for (i=0; i<len; i++)
{
outd[i]=0.0;
}

// initialise the int to a value
outI = 0;

// initialise the global int to a value
globalI = 5;

// initialise one of the two twins
unknownTwinI = 6;
}

// show the content of the buffer referenced by the pointer
// and the value of the integer
void showarray(int len, int iterno)
{
int i;

// make a function local, non-static integer
int locI =0; // this init happens every time the functin is executed
// make a function-local, but static integer
static int inI =0; // this init happens before the first execution of the function

printf("iteration %d, array is \n",iterno);
for (i=0; i<len; i++)
{
outd[i]=outd[i]+iterno; // "counting up" array contents
printf("%.2f ",outd[i]);// show
}
outI = outI + iterno; // "counting up" file-local integer value
printf(" outI:%d", outI); // show

inI = inI + iterno; // "counting up" the function-local static integer
printf(" inI:%d", inI); // show

locI = locI + iterno; // "single increase" the function-local integer
printf(" locI:%d", locI); // show

globalI = globalI + iterno; // "single increase" the function-local integer
printf(" globalI:%d", globalI); // show

unknownTwinI = unknownTwinI + iterno; // "single increase" the function-local integer
printf(" unknownTwinI:%d", unknownTwinI); // show

// Note that nothing here frees the buffer
// or changes the pointer (which would be highly questionable, thinking of the free() later

printf("\n");


}

void deletearray()
{
free(outd);
}

代码1.c:

#include <stdio.h>
#include <stdlib.h>

void init0(int len);
void showarray(int len, int iterno);
void deletearray();

// declare the global integer, which is defined in code2.cabs
// (should be in a header.h,
// excuse me for taking a shortcut for only having two files to post)
extern int globalI;

// attempt to similarly declare some of the identifiers which cannot be accessed
extern double *outd;
extern int outI;
extern int inI;
extern int locI;

// define an int which is only visible from this file,
// but has an identically named twin in the other file
// (there be dragons)
static int unknownTwinI;

int main(int argc,char* argv[])
{
int i, len;
len=5;

// exception of an init outside of init0(),
// this one targets the twin in THIS file here
unknownTwinI =0;

// pointer gets address, buffer gets values
// integers (those not static to showarray) get values
init0(len);

for (i=0; i<7; i++)
{
// all kinds of counting gets done
// (only during the first execution
// the local static int initially has the init value)
showarray(len,i);

// demonstrating that the global integer is accessable
globalI = globalI * 2;

// the showarray outputs the value of the twin in the other file,
// attempting to resist/undo the cumulative changes done there
unknownTwinI =0;
// (resistance is futile)

// these are forbidden accesses,
// with the warnings you get WITHOUT trying to declare them

// outd=NULL; // 'outd' undeclared (first use in this function)
// outI=0; // 'outI' undeclared (first use in this function)
// inI = 0; // 'inI' undeclared (first use in this function)
// locI =0; // 'locI' undeclared (first use in this function)



// these are the forbidden accesses again,
// with the warnings you get WITH trying to declare them

// outd=NULL; // undefined reference to `outd'
// outI=0; // undefined reference to `outI'
// inI = 0; // undefined reference to `inI'
// locI =0; // undefined reference to `locI'
}

deletearray();

return 0;
}

输出:

iteration 0, array is
0.00 0.00 0.00 0.00 0.00 outI:0 inI:0 locI:0 globalI:5 unknownTwinI:6
iteration 1, array is
1.00 1.00 1.00 1.00 1.00 outI:1 inI:1 locI:1 globalI:11 unknownTwinI:7
iteration 2, array is
3.00 3.00 3.00 3.00 3.00 outI:3 inI:3 locI:2 globalI:24 unknownTwinI:9
iteration 3, array is
6.00 6.00 6.00 6.00 6.00 outI:6 inI:6 locI:3 globalI:51 unknownTwinI:12
iteration 4, array is
10.00 10.00 10.00 10.00 10.00 outI:10 inI:10 locI:4 globalI:106 unknownTwinI:16
iteration 5, array is
15.00 15.00 15.00 15.00 15.00 outI:15 inI:15 locI:5 globalI:217 unknownTwinI:21
iteration 6, array is
21.00 21.00 21.00 21.00 21.00 outI:21 inI:21 locI:6 globalI:440 unknownTwinI:27

关于c - 使用静态指针的动态内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44613248/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com