外部字符串调用导致32位的Segfault,在64位

时间:2017-08-28 17:39:16

标签: c++

我正在编写一个程序,它从已编译的静态库中调用外部字符串数组。 当我在 64位中编译和运行程序时,它可以正常工作。但是,当我在* 32位*中编译代码时尝试调用外部数组时,它在运行main时会出现分段错误。

以下是代码:

标题声明" hoenyB_lib.h:

#ifndef HONEYB_LIB_H_
#define HONEYB_LIB_H_

#include <string>

 extern std::string honeyB_libs[];

#endif

外部定义HoneyB_lib.cpp:

#include <string>

std::string honeyB_libs[] = { "libHoneyB.so", "libHoneyB3.so", "libHoneyB2.so", "" };

外部使用HoneyB_fcn.cpp:

deque<string> get_array()
{
    deque<string> dst;
    int i =0;

    for(;;)
    {
        if(honeyB_libs[i] == "")
            break;
        else
        {
            dst.push_front(honeyB_libs[i]);
            i++;
        }
    }
    return dst;
}

编译它的Makefile如下:

all:
    $(CC) -c -Wall -fPIC source.cpp
    $(CC) -g -c -fPIC honeyB_fcn.cpp
    ar rcs libHB.a honeyB_fcn.o
    g++ -g -c -fPIC honeyB_lib.cpp
    g++ --whole-archive -shared -o libHoneyB.so source.o honeyB_lib.o libHB.a
    g++ -L. -o main main.cpp -lHoneyB

调用main()时,这没有问题。但是,当我使用以下代码编译为 32位时:

all32:
    $(CC) -m32 -c -Wall -fPIC source.cpp
    $(CC) -m32 -g -c -fPIC honeyB_fcn.cpp
    ar rcs libHB.a honeyB_fcn.o
    g++ -m32 -g -c -fPIC honeyB_lib.cpp
    g++ --whole-archive -m32 -shared -o libHoneyB.so source.o honeyB_lib.o libHB.a
    g++ -m32 -L. -o main main.cpp -lHoneyB

代码给出了分段错误。如果我将honeyB_fct.cpp中的呼叫移至honeyB_libs[],则代码会编译并执行。

有没有人知道为什么 32位失败了,但适用于 64

提前致谢。

2 个答案:

答案 0 :(得分:0)

未定义不同翻译单元之间的初始化顺序。您无法保证HoneyB_lib.cpp中的全局变量在HoneyB_fcn.cpp中使用之前会被初始化。它适用于64位版本的唯一原因是因为你很幸运。

有几种解决方法:

  1. honeyB_lib.h中定义数组,包含在匿名命名空间中以绕过ODR。每个包含标题的TU都有自己的数组副本。
  2. 再次,在标头中定义数组,但将其放在返回数组的函数内。编译器在任何地方优化它,但如果不是,你可以在函数范围内使数组静态并通过引用返回(即使它成为单例)。
  3. 作为旁注,我建议使用std::array而不是原始数组;这样您就可以执行honeyB_libs.size()(甚至for (auto&& lib : honeyB_libs) {...}),而不是依赖""哨兵值,这会稍微清理您的get_array函数。

答案 1 :(得分:0)

感谢您的帮助。问题似乎与 32位 vs 64-bit 中的字符串位数有关。将 honeyB_libs [] 从字符串数组更改为const char *数组解决了这个问题。 honeyB_lib.h

extern const char* honeyB_libs[];

honeyB_lib.cpp

const char* honeyB_libs[] = { "libHoneyB.so", "libHoneyB3.so", "libHoneyB2.so", "" }

function.cpp

deque<string> get_array()
{
   deque<string> dst;
   string temp;
   int i =0;

   for(;;)
   {
    if(strlen(honeyB_libs[i]) == 0)
        break;
    else
    {
        temp = honeyB_libs[i];
        dst.push_front(temp);
        i++;
    }
   }

  return dst;
}

这样做可以让我的程序编译并运行为 64位 32位