无法访问外部文件中定义的数组,W/O关键字"extern"

wal*_*ala 4 c c++ arrays

我发现无论如何,我都无法访问外部文件中定义的数组.所以我在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)

你可以看到非常简单的测试.无论我用什么方法访问外部文件中的数组,我都会遇到分段错误.

mol*_*ilo 6

变量链接不是类型安全的.

问题是你要定义名称"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)

而当你strcat0,事情不顺利.

如果在数组中存储比零更明显的内容(例如"\1\2\3\4")并检查调试器中的指针,则更明显的是数组的元素"成为"指针的值.

解决方法是做出正确的主张; 这arr是一个数组:

extern char arr[];
Run Code Online (Sandbox Code Playgroud)

(注意,在变量声明,而不是函数的参数,char arr[]一样的char* arr.)