从linux切换到windows时,我注意到我的代码停止了工作。使用可靠的调试器,我发现结构体的初始化方式不同。
typedef struct base{
struct item * first;
}BASE;
typedef BASE *SPACE;
...
hashmap = malloc(sizeof(SPACE *) * length);
hashSpaceSize = length;
请查看此代码示例(隐藏额外代码以保持整洁,同时忽略 struct item 它在这里没用)。让我们说长度为3.在Linux中,当我检查调试器时,我看到:
hashmap[0] = NULL;
hashmap[1] = NULL;
hashmap[2] = NULL;
因为我没有初始化BASE,所以我只是初步确定了它们的数组。但是,在Windows中,我看到所有BASES都已初始化。不仅如此,BASE中的所有ITEM都已初始化。
但是,如果我,例如,之后立即添加此行:
hashmap[0]->first = NULL
,我最终得出SIGSEGV
错误,我无法找到原因。在Linux中,这是因为hashmap[0] is NULL
,因此hashmap[0]->first
甚至无法首先访问。但在Windows上,它清楚地表明hashmap [0]存在并且具有初始化first
值。
我不知道这里发生了什么,我找不到任何有关此错误的信息。如果需要更多代码,那么我的github.上的所有内容都与此代码所在的实际文件相关联。但就目前而言,我对发生的事情感到困惑......
更新:显然我有一些想要做的事情。我不知道malloc返回了一个未初始化的指针,而不仅仅是NULL。那是由Linux设定的。谢谢,今天学到了新的东西。
答案 0 :(得分:2)
假设长度为3.在Linux中,当我检查调试器时,我明白了 的是:
def split(s, n): """ Split string every nth character Parameters ---------- s: string n: value of nth """ new_list = [] for i in range(0, len(s), n): new_list.append(s[i:i+n]) return new_list print(split('1234567890', 2))
因为我没有初始化BASE,所以我只是初步了解了这个事实 他们有一个阵列。
没有。你得到的所有这些都是hashmap[0] = NULL;
hashmap[1] = NULL;
hashmap[2] = NULL;
,因为这恰好就是你得到的。 C没有指定NULL
返回的内存的初始内容,如果在其他情况下执行了该分配,则可能无法获得所有NULL。
然而,在Windows中,我看到了全部 BASES已初始化。不仅如此,还有所有的ITEM BASE也是初始化的。
它们可能具有非NULL值,但这与初始化非常不同。这些值很可能是狂野的指针。如果它们碰巧指向可访问的内存,那么您可以将它们指向的数据解释为malloc()
s,但同样,这并不意味着它们已初始化,或者访问该内存是安全的。您正在深入研究未定义的行为。
但是,如果我,例如,之后立即添加此行: hashmap [0] - > first = NULL,我最终得到一个SIGSEGV错误,我不能 找到原因。
我们无法说出您的分段错误的原因,因为您没有提供负责的代码,但拥有一个指针数组并不意味着其中的指针值是有效的。如果不是,则取消引用它们会产生未定义的行为,这通常表现为段错误。请注意,这不依赖于那些指针为ITEM
;它可以访问任何指针值,该值不指向属于您的程序且具有兼容类型的对象。
在Linux中,这是因为hashmap [0]为NULL,并且 因此,首先甚至无法访问hashmap [0] - >。但 在Windows上,它清楚地表明hashmap [0]存在且具有 初始化的第一个值。
不,它没有。同样,您的调试器显示NULL
具有非hashmap[0]
值,这完全不同。
您有责任避免取消引用无效指针值,这些值绝不仅限于NULL
。
答案 1 :(得分:1)
成功调用malloc
后指向的字节值未初始化。这意味着它们可以设置为任意值,包括零。因为字节为零或非零并不意味着它们被初始化。
关于malloc
州C standard的第7.22.3.4节:
1
#include <stdlib.h> void *malloc(size_t size);
2
malloc
函数为一个对象分配空间,该对象的大小由size
指定,其值不确定。
因此无法保证malloc
返回的内存包含的内容。
如果另一方面使用calloc
,该函数会将所有分配的字节初始化为0。
hashmap = calloc(length, sizeof(SPACE *));