Linux和Windows初始化结构不同

时间:2017-12-12 19:34:51

标签: c struct malloc

从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设定的。谢谢,今天学到了新的东西。

2 个答案:

答案 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后指向的字节值未初始化。这意味着它们可以设置为任意值,包括零。因为字节为零或非零并不意味着它们被初始化。

关于mallocC 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 *));