我发现无论如何,我都无法访问外部文件中定义的数组.所以我在c和c ++中做了一些简单的测试:
在C:
main.c中
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int func();
char arr[100]="";
int main()
{
for(int i=0;i<=9;++i){
func();
printf("%s\n",arr);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
func.c
#include<string.h>
#include<stdio.h>
extern char* arr;
int func(){
strcat(arr,"hello"); // try to access arr here
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在C++中:
main.cpp中
#include<iostream>
using namespace std;
int func();
char arr[100]="";
int main()
{
for(int i=0;i<=10;++i){
func();
cout<<arr<<endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
func.cpp
#include<cstring>
extern char* arr;
int func(){
strcat(arr,"hello"); // try to access arr here
return 0;
}
Run Code Online (Sandbox Code Playgroud)
你可以看到非常简单的测试.无论我用什么方法访问外部文件中的数组,我都会遇到分段错误.
变量链接不是类型安全的.
问题是你要定义名称"arr"来引用数组.
假设数组位于地址0x10,它看起来像这样:
Address 0x10 0x11 0x12 0x13
Content | 0 | 0 | 0 | 0 | (... 100 zeroes in total)
Run Code Online (Sandbox Code Playgroud)
名称"arr"指的是存储此数组的位置.
在"func.cpp"(和"func.c" - 它们完全相同)中,您声明或声明名称"arr"指的是指针.
这是一个谎言,因为它不是你定义它的,但编译器和链接器盲目地信任你.
这个谎言导致代码func将存储在地址0x10的值解释为指针而不是数组.
使用32位指针,即可
Address 0x10 0x14
Content | 0 | 0 | (...)
Run Code Online (Sandbox Code Playgroud)
而当你strcat在0,事情不顺利.
如果在数组中存储比零更明显的内容(例如"\1\2\3\4")并检查调试器中的指针,则更明显的是数组的元素"成为"指针的值.
解决方法是做出正确的主张; 这arr是一个数组:
extern char arr[];
Run Code Online (Sandbox Code Playgroud)
(注意,在变量声明,而不是函数的参数,char arr[]是不一样的char* arr.)