已解决请参阅问题的底部以获得解决方案。
我在向函数传递String参数时遇到问题,并且在调用函数时遇到分段错误。该程序接受命令行输入并在验证后传递提供给该函数的文件。
我的功能代码如下:
char *inputFile; //
inputFile= argv[2];
strcpy(inputFile, argv[2]);
compress(inputFile){
//file open and creation work bug-free
//compression action to be written
void compress(char inputFile){
//compression code here
}
当调用该函数时,抛出段错误,并且inputFile的值为0x00000000,在函数调用之前,它具有内存位置和测试文件路径的值。
我尝试过的一些变体,匹配函数原型:
compress(char *inputFile)
compress (char inputFile[])
我也改变了变量。
为什么调试器中具有有效内存地址和值的变量在用作参数时会突然擦除?
修改1:
在此处添加建议,我删除了inputFile= argv[2]
行,调试器显示strcpy
函数正常工作。
但是,我已经尝试了每个Edwin Buck compress(char *inputFile)
和compress(argv[2])
每个展开,两个更改仍会导致Cannot access memory at address 0xBEB9C74C
奇怪的是我的文件验证函数checkFile(char inputFile[])
与inputFile
值一起使用,但是当我将相同的参数传递给compress(char inputFile[])
函数时,我得到了段错误。
编辑2已解决
你知道当你教授45分钟的时候会发生一些事情。事实证明,我已经将文件读取缓冲区声明为compress()方法中的5MB长数组,这反过来最大化了堆栈帧。将缓冲区声明更改为全局变量就可以了,并且代码会执行。
感谢您的帮助!
答案 0 :(得分:4)
您不应该写入用于保存argv[2]
的内存。
您似乎并不完全理解字符串的表示方式;你要复制指针(带有赋值)和实际字符(用strcpy()
)。
一旦您确认该参数有效,您应该compress(argv[2]);
。
答案 1 :(得分:2)
首先,要将某些内容从argv[2]
复制到其他地方,您需要一些“其他地方”的内存。你可以根据argv[2]
的大小来分配内存,但是对于我们的简单例子,一个非常大的固定大小的缓冲区就可以了。
char inputfile[2048];
看起来你试图通过赋值运算符来实现这一点,它实际上并不是你想要的。
// this is not the way to what you seek, as it doesn't create any new memory for inputfile
char* inputfile = argv[2];
在将inputfile
变量传递给过程时,您希望传递多于一个字符,因此void compress(char inputfile)
不是一个选项。离开
compress(char *inputFile) // I prefer this one
compress (char inputFile[])
这两者都有效,但根据我的经验,第一个是首选,因为一些较旧的编译器倾向于区分指针和数组语义。这些编译器没有问题将数组转换为指针(这是C语言规范的一部分);但是,在这样的系统中,向数组投射指针会有点混乱。
答案 2 :(得分:0)
您没有为char *分配任何内存。您使用char * inputfile完成的所有操作都会被分配一个指针。