【问题标题】:accessing elements of dynamiclly allocated array访问动态分配数组的元素
【发布时间】:2015-09-26 16:38:07
【问题描述】:

我试图通过将占位符数组的大小添加到第一个元素来访问动态分配的下一个元素。占位符数组的大小是 4 个字节,所以如果我将 4 个字节添加到地址为 2147549788 的第一个元素,我应该查看下一个内存位置 2147549792。但是,我正在查看 16 个字节 2147549804 中的地址。如果我读数组元素的地址直接我得到了正确的地址。想知道为什么添加占位符的大小会产生不同的结果? 此外,如果我在 for 循环之外访问第二个元素的位置,则该位置会再偏移 16 个字节,即 2147549820

#include "stdio.h"
#include "time.h"
#include <stdlib.h>
#include <string.h>

typedef struct Section {
    int numOfStudents;
} Section;

typedef struct School {
    int schoolId;
    Section sections[1]; //placeholder
} School;

int main(void) 
{
    School *schoolA_p;  
    Section section1;
    int sizeOffset = 0;
    int i,sectionSize;

    int sizeOfSchool = sizeof(School) - sizeof(Section) + (sizeof(Section)*2);
    schoolA_p = (struct School *) malloc(sizeOfSchool);

    for(i=0;i<2;i++)
    {
        sectionSize = sizeof(Section);

        printf("\nsize of section = %d\n", sizeof(Section));
        printf("Number of bytes to add to first element to access the next element = %d\n", sizeOffset);
        printf("In Loop Location of schoolA_p->sections[%d]= 0x%lx\n",i, &(schoolA_p->sections[0]) + sizeOffset);

        sizeOffset += sectionSize;
    }

    printf("\n Location of schoolA_p->sections[0]= 0x%lx\n",&(schoolA_p->sections[0]));
    printf("\n Location of schoolA_p->sections[1]= 0x%lx\n",&(schoolA_p->sections[1]));

    printf("\n Outside of lopop Location of schoolA_p->sections[0]= 0x%lx\n", &(schoolA_p->sections[0])+ sizeOffset);

    free(schoolA_p); 
    return 0;
}

【问题讨论】:

  • 在循环调用中,您忘记了 &。 schoolA_p->sections[0] -> &schoolA_p->sections[0] .
  • @jas 你能分享你得到的 o/p 吗?
  • 假设忘记的“&”是问题中的拼写错误,您是否只是忘记了 C 指针算法考虑了项目的大小?所以 p + 4 步骤 4 数据对象 向前,而不是 4 个字节。
  • 你应该使用格式说明符%p来打印一个指针,它应该被强制转换为void*,例如printf("%p",(void*)ptr)
  • 我忘了&。但我想问题是指针算术,我假设它向前 4 个字节。没有意识到这将是 4 个数据对象。谢谢!

标签: c arrays


【解决方案1】:

指针算法的工作原理如下:如果p 是指向数组元素a[n] 的指针,那么p + i 是指向a[n + i] 的指针。换句话说,指针算术以指针声明的任何基本类型为单位移动,而不是字节。

【讨论】:

    【解决方案2】:

    C 指针算法会在您增加指针时考虑指向的数据的大小。

    所以如果p是一个指向4字节数据的指针,p + 1会计算p之后4字节的地址。

    换句话说,你做了太多的工作。 C 为您记账,这就是您得到错误结果的原因。

    附带说明,这就是为什么您不能对void* 指针使用指针运算。指向的数据大小未指定。

    【讨论】:

    • 旁注:gcc 允许在 void * 上进行算术运算作为扩展(将其视为 char *)。
    • @melpomene 我不知道。这实际上很有趣。它看起来真的很不安全,我永远不会建议这样做,但无论如何 C 并不是一种真正“安全”的语言。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 2011-12-10
    • 2020-10-24
    • 2016-12-13
    • 2021-06-29
    • 2019-07-19
    • 2022-11-13
    相关资源
    最近更新 更多