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

2024-05-19

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

In 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);
}

In 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

Running

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);
}

code1.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;
}

Output:

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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用静态指针的动态内存分配 的相关文章

随机推荐

  • MySql 视图脚本中的注释

    可以这样做吗 我尝试过多个 gui mysql workbench navicat toad for mysql 但没有一个保存这样的注释 something important select something else importan
  • 迁移到 ARC 时如何解决“选择器'performSelector:withObject:afterDelay:'没有已知的实例方法”?

    ARC 迁移工具在开始迁移之前拒绝接受此代码 self delegate performSelector selector overlayDismissed withObject self afterDelay 0 委托被迫使用协议来实现此
  • 在流体设计中将元素的宽度调整为其高度的百分比,反之亦然? [复制]

    这个问题在这里已经有答案了 我正在制作响应式设计 无论屏幕尺寸是什么 它都必须保持其元素的比例 高度与宽度 所以我不知道任何元素的像素大小 并且我只能以 工作 我可以将宽度或高度设置为浏览器大小的百分比 但我不知道如何设置其他属性值 仅使用
  • Android 运行时中的 Appworld 市场链接

    我在应用程序世界上有一个应用程序 我想在我的应用程序中添加一个指向它的链接 以便人们可以更轻松地对其进行评分 通常在 android 市场上我会这样做 Uri uri Uri parse market details id com exam
  • R,使用具有两种以上可能性的二项式分布

    我知道这可能是基本的 但我似乎有一个心理障碍 假设您想要计算在一个骰子上掷出 4 5 或 6 的概率 在 R 中 这很简单 sum 1 6 1 6 1 6 这给出了 1 2 这是正确答案 然而 我内心深处 可能应该保留的地方 认为我应该能够
  • JSTL 日期比较

    我看过一些关于 JSTL 中日期比较的帖子 但我仍然无法让它工作 我有一个日期字段 我想测试它是否在之后01 01 1970
  • 在多个动态添加的表单上初始化 jQuery validate() 函数

    有人建议最好初始化一个 form validate 在页面加载而不是点击事件上运行 jquery form validate 插件仅允许在输入更改时提交 https stackoverflow com questions 10984196
  • 如何按定义的顺序将图像合并到一个文件中

    我有大约 100 张图像 png 我不想手动执行此操作 而是希望将它们按照定义的顺序 基于文件名 并排放置在一个 pdf 中 每行 12 个图像 有人有什么建议吗 我按照下面托马斯告诉我的方法尝试了 它把它们贴在旁边有一个黑边 我怎样才能去
  • 如何自动缩放mapView以显示叠加层

    我可以在 mapView 上绘制多边形 但是我需要找到多边形并手动缩放它 有没有办法自动执行此过程 例如调整中心多边形 我浏览过互联网并阅读了一些相关文章 其中大多数都是基于折线和点的 任何形式的帮助将不胜感激 因为我正在寻找解决方案一段时
  • SQL:如何从一个表中获取另一个表中每一行的随机行数

    我有两个数据不相关的表 对于表 A 中的每一行 我想要例如表 B 中的 3 个随机行 使用光标这相当容易 但速度非常慢 那么我该如何用单个语句来表达这一点以避免 RBAR 呢 要获得 0 到 N 1 之间的随机数 可以使用 abs chec
  • Pandas 交叉表与 Pandas 数据透视表有何不同?

    两只熊猫的crosstab and pivot table函数似乎提供完全相同的功能 有什么区别吗 两者之间的主要区别是pivot table期望您的输入数据已经是一个 DataFrame 你将一个 DataFrame 传递给pivot t
  • Android Studio 在编译时未检测到支持库

    由于 Android Studio 将成为 Android 开发的默认 IDE 因此我决定将现有项目迁移到 Android studio 中 项目结构似乎不同 我的项目中的文件夹层次结构如下 Complete Project gt idea
  • 无法读取未定义的“触及”属性

    为什么我会收到此错误无法读取未定义的属性 为什么无法读取formName controls email touched但它能够阅读formName get custDetails touched
  • 使用面向对象的分析和设计对电梯进行建模[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 当涉及到面向对象的设计和分析时 有一组问题似乎在面试和课堂上很常见 这是其中之一 不幸的是 我在大学的 OOP 教授从未真正给出过答案 所以我一
  • 在Python中,如何将矩阵逆时针旋转90度?

    gt gt gt def rotate matrix k List List int For example if I have m 1 2 3 2 3 3 5 4 3 rotate matrix m should give me 3 3
  • 使用sk_buff添加以太网帧头

    我有一个捕获传出互联网流量的内核模块 Netfilter hook LOCAL OUT 在此挂钩处 仍然没有以太网标头 我构建了以太网头并且可以使用了 但是如何将其连接到skb这样我就可以将整个 skb 结构发送到dev queue xmi
  • 如何覆盖 bootstrap 表 td 样式?

    我正在使用 Bootstrap 3 3我有一个 HTML 代码如下 div table class table table striped tr td 03 td td 04 td td 05 td td 06 td td 07 td td
  • 在 iOS 模拟器中安装应用程序的脚本

    我正在尝试自动化构建应用程序 运行单元测试以及最终运行 UI 测试的过程 我正在通过命令行 xcodebuild sdk iphonesimulator6 0 在某个目录中构建应用程序 如何通过命令行 在 Library Applicati
  • Angularjs 完整日历不显示事件

    我正在用那个https github com angular ui ui calendar https github com angular ui ui calendar在 Angularjs 中使用 FullCalendar 它显示日历并
  • 使用静态指针的动态内存分配

    有人可以向我解释一下为什么下面的代码会这样工作吗 这里我已经初始化了outd作为文件中的静态指针code2 c 然后我动态地为其分配内存malloc 从单独文件中的主函数中一次又一次地调用它code1 c 它看起来整个数组以静态方式运行 因