【问题标题】:C: Returned char array becomes garbage [duplicate]C:返回的char数组变成垃圾[重复]
【发布时间】:2014-07-20 08:36:33
【问题描述】:

问题是函数返回值SQLStatement。它完全按照我想要的方式生成(在调试模式下检查),但是当我在 main() 中调用函数时,有一个垃圾作为返回值。函数和示例代码如下:

char *GenerateSQLStatement(char *SQLQuery){

size_t SQLQueryCounter = 0;
size_t TableNameCounter = 0;
size_t CVIQueryConstantCounter = 0;

while(SQLQuery[SQLQueryCounter] != '\0') SQLQueryCounter++; 
while(TableName[TableNameCounter] != '\0') TableNameCounter++;
while(CVIQueryConstant[CVIQueryConstantCounter] != '\0') CVIQueryConstantCounter++; 

char SQLStatement [CVIQueryConstantCounter + TableNameCounter + SQLQueryCounter + 1];

for (int i = 0; i <= (CVIQueryConstantCounter + TableNameCounter + SQLQueryCounter); i++) SQLStatement[i] = '\0';

strcat(SQLStatement, CVIQueryConstant);
strcat(SQLStatement, TableName);
strcat(SQLStatement, SQLQuery);

return SQLStatement;    
}

void main(){
char *SQLStatement = GenerateSQLStatement("test");
}

有什么想法吗?

【问题讨论】:

  • 为什么不使用strlen 来计算字符串长度?此外,您需要动态分配SQLStatement 和malloc,因为在函数调用完成后它将超出范围。或者,strcpy 的结果与函数调用(或 strdup)在同一行。
  • Strlen - 完全忘记了。使用malloc时何时释放内存?如果我在函数中执行它与我已经执行的操作相同,那么该数组将不会存在于函数之外?
  • 你的代码现在的样子,SQLStatement 是栈上的一个局部变量。它只存在于函数的范围内。函数返回后,该内存不再有效。通过在函数调用的同一行上使用strcpy 或strdup,您可以在内容超出范围之前对其进行复制。您使用malloc 创建比当前范围持续更长 的内存。在您调用 free 之前,可以使用该内存(当您不再需要该内存时,您会这样做)。
  • 您在使用后释放内存,在本例中是在 main() 函数中。如果你在函数中释放它,缓冲区是无效的,它的地址不应该被返回。
  • 另外,使用memset() 或bzero() 或类似方法将数组归零 - 它可能比for 循环更有效(但不一定保证如此 - 取决于硬件功能,编译器版本和优化设置)并且更具可读性...

标签: c arrays dynamic char


【解决方案1】:

初学者的错误:您正在返回一个指向堆栈上数据的指针。当函数返回时,指针指向的数据就消失了。

我还建议您学习使用 strlen、strcpy 和 memset 函数。然后询问某人什么是缓冲区溢出,以及为什么您的代码可能会创建缓冲区溢出。最后看一下strlcpy和strlcat函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    • 2021-08-07
    • 2013-03-19
    • 2012-12-10
    • 1970-01-01
    相关资源
    最近更新 更多