【发布时间】: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循环更有效(但不一定保证如此 - 取决于硬件功能,编译器版本和优化设置)并且更具可读性...