【问题标题】:long integer as array index in C gives segmentation fault长整数作为 C 中的数组索引会导致分段错误
【发布时间】:2010-10-13 14:44:00
【问题描述】:

以下 C 代码给出了分段错误:

#include <stdio.h>
#include <stdint.h>

int main(){
        uint32_t *a;
        uint32_t idx=1233245613;
        a[idx]=1233;
        return 0;
}

如何在 C 中使用 uint32_t 作为数组的索引?或者如何使用可以获取 uint32_t 和 12 位数字作为索引的数组结构?

如果能提供任何帮助,我将不胜感激。

【问题讨论】:

    标签: c pointers segmentation-fault


    【解决方案1】:
    • 变量“a”只是一个指针变量。
    • 指针变量保存内存位置的地址。
    • 您需要将 a 指向已分配所需空间的内存位置。

    您还试图在数组中索引很远。您可能没有足够的可用内存,因此请务必检查 NULL。

    #include <stdio.h>
    #include <stdint.h>
    #include <stdlib.h>
    
    int main(void){
    
            uint32_t *a;
            uint32_t idx=1233245613;
    
            //This allows you to index from 0 to 1233245613
            // don't try to index past that number
            a = malloc((idx+1) * sizeof *a);
            if(a == NULL)
            {
               printf("not enough memory");
               return 1;
            }
    
    
            a[idx]=1233;
            free(a);
            return 0;
    }
    

    【讨论】:

    • Thanx Brian 添加 #include 解决了我的问题。我已经很长时间没有使用 c,所以我忘记了当今垃圾收集世界的基础知识:D。
    • 谢谢,我在答案中添加了这个标题。
    • 在 C++ 中有些不同。首先,使用 std::vector,而不是数组。其次,如果必须使用数组,请考虑 new[]。第三,如果您确实使用了 malloc(),则必须转换结果。这是优秀的 C,但不会在 C++ 中编译。
    • 我认为无法容纳 12 亿个元素将成为几乎任何语言的“基本”。
    【解决方案2】:

    如果您想使用“12 位数字”作为索引,这意味着您需要超过 10 亿个项目。每个项目都是一个 uint32_t,这意味着每个项目占用四个字节的内存。因此,您正在查看此阵列的总内存约为 4 GB。出于性能和其他原因,数组通常不会那么大。

    如果您真的需要这十亿个项目中的每一个,请查看适合实现这种巨型数组的磁盘支持算法,也许是 Red-Black Trees

    【讨论】:

    • 将新项目添加到大小将是疯狂的红黑树所需的旋转量,所以这肯定是一个糟糕的解决方案?
    • 编程珍珠第一章:D
    • 此外,无论您如何存储它(除非它是稀疏数组,但是为什么要使用类似数组的结构),您将达到 32 位的内存限制过程。您需要 64 位操作系统和编译器。
    • 在数组上使用红黑树的决定与您如何使用数据有关,与数据的大小无关。红黑树不会减少内存占用,它会增加读/写时间,同时减少搜索时间。如果您要进行大量搜索,这很好,如果您要进行大量直接索引,则这是一个非常糟糕的主意。在任何一种情况下,OP 都没有提供足够的信息让某人建议替代算法。
    【解决方案3】:

    对于初学者来说,您需要为 a 分配空间。

    当该代码运行时,a 指向您可能不拥有的内存空间。
    当您尝试访问它时(实际上是当您尝试访问 + 1233245613 时),您将进入您绝对不拥有的内存空间,这是一个禁忌,会导致崩溃。

    #include <stdio.h>
    #include <stdint.h>
    
    int main(){
            uint32_t *a;
            uint32_t idx=1233245613;
            a = malloc(sizeof(unit32_t) * (idx+1));//+1 cause remember, arrays are 0-based
            if(a == NULL) 
            {
               printf("Array could not be allocated"); 
               return 1;
            }
            a[idx]=1233;
            free(a);//good practice to avoid memory leaks
            return 0;
    }
    

    但即使这样也不能解决您使用 GIANT 数组的问题。您的标准设置(台式机甚至大多数服务器)在尝试分配 4.6GB 内存时会卡住。因此,除非您考虑到这一点,否则您可能需要退后一步,重新考虑您要做什么以及如何做。

    【讨论】:

    • 您可能想使用“if (a != NULL)”来检查是否成功,因为这会尝试分配大约 4.9 GB 的内存。
    【解决方案4】:

    你需要两件事:

    • a数组分配内存,类似于uint32_t a[2000000000];
    • 在可寻址超过 4Gb 内存的 64 位架构上编译。

    【讨论】:

      【解决方案5】:

      哇哦。搞砸了。

      好的。这里有两个问题。第一个问题是您声明了一个指向整数的指针,从未将它指向任何东西,然后尝试使用它。这只是一个错误。最有可能的是,指针恰好指向一个甚至不是您的进程的有效内存的地方(或指向 NULL)。在这种情况下,任何尝试使用它都会给你一个段错误,就像你得到的一样。

      第二个问题是你试图索引它的值。即使您为指针分配了内存,我也严重怀疑您是否可以为它分配 4.8 GB。大多数计算机没有那么多内存,而且在一个连续的块中肯定没有那么多。如果您尝试对分配给数组的内存进行索引,那么任何事情都可能发生,但是如果您方式过去,您很可能会遇到段错误。

      【讨论】:

        【解决方案6】:

        a 是一个指向任何确定的指针。你想要一个数组

        uint32_t a[42];
        

        创建一个由 42 个整数组成的数组。但是,您对它的访问仍然会导致问题(确切地说是未定义的行为),因为它超出了此数组或任何其他合理数组的范围。

        【讨论】:

          猜你喜欢
          • 2019-12-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-25
          • 2010-12-18
          • 2017-02-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多