1

已解决请参阅问题底部的解决方案。

我无法将字符串参数传递给我的函数,并且在调用函数时遇到分段错误。该程序接受命令行输入并在验证后将提供给函数的文件传递给该函数。

我的功能代码是这样的:

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功能正常工作。

但是,我都尝试过compress(char *inputFile)每个 Edwin Buck 和compress(argv[2])每个 unwind,这两种更改仍然会导致Cannot access memory at address 0xBEB9C74C

奇怪的是我的文件验证功能checkFile(char inputFile[])适用于inputFile值,但是当我将相同的参数传递给compress(char inputFile[])函数时,我得到了段错误。

编辑 2- 已解决

当你难倒你的教授 45 分钟时,你就知道发生了什么事。事实证明,我在 compress() 方法中将文件读取缓冲区声明为一个 5MB 长的数组,这反过来又最大化了堆栈帧。将缓冲区声明更改为全局变量就可以了,代码就会执行。

谢谢您的帮助!

4

3 回答 3

4

您不应该写入用于保存的内存argv[2]

您似乎不太了解字符串的表示方式;您正在复制指针(带有赋值)和实际字符(带有strcpy())。

compress(argv[2]);一旦您验证了该论点是有效的,您就应该这样做。

于 2011-03-01T15:44:05.807 回答
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 语言规范的一部分);但是,在这样的系统中,将指针转换为数组会有点混乱。

于 2011-03-01T15:51:49.567 回答
0

您没有分配任何内存供 char * 使用。您对 char *inputfile 所做的一切都分配了一个指针。

于 2011-03-01T15:45:38.337 回答