![](/img/trans.png)
[英]What's wrong with my C code(My output is volatile because of malloc)?
[英]C - What's wrong with my code (malloc, char*)
我只想让您问一下这段代码我做错了什么。 我编写了一个在参数中带有char *的函数,我想直接对其进行修改而不返回smthg,并反转字符串。
#include <iostream>
void reverseString(char *p_string){
int length = strlen(p_string);
int r_it = length - 1;
char* tmp = (char*)malloc(length);
int last_it = 0;
for (int i = 0; i != length; i++){
tmp[i] = p_string[r_it];
r_it--;
last_it++;
}
tmp[last_it] = '\0';
strcpy_s(p_string, length + 1, tmp);
//free(tmp);
}
int main(){
char str[] = "StackOverflow";
reverseString(str);
std::cout << str << std::endl;
system("pause");
}
我已经习惯了C ++,并且不经常使用C函数,例如malloc / free / strcpy ...在这里,我的问题是,当我为临时char分配内存时,我在这里以length = 13的方式调用了Mallec(length)情况下,char = 1个字节,因此应该为13个char分配内存,对吗?
问题是分配了比需要更多的空间,因此我需要在我的strcpy_s之前使用“ \\ 0”,否则它不会中断。
我在某个地方犯错了吗? 另外,当我调用free(tmp)时,它也会中断并说堆损坏,但是在此之前我没有释放内存。
感谢您的帮助!
我使用了原始代码,并在malloc的大小上添加了一个简单的“ +1”,并获得了通过的结果。
不知道您的练习是否专门与malloc的使用有关,但是您是否考虑过直接在原始字符串中进行反转?
例如:
void reverseString(char *p_string){
char* p_end = p_string+strlen(p_string)-1;
char t;
while (p_end > p_string)
{
t = *p_end;
*p_end-- = *p_string;
*p_string++ = t;
}
}
int main(){
char str[] = "StackOverflow";
reverseString(str);
std::cout << str << std::endl;
system("pause");
}
如果需要使用malloc,则需要确保为包含'\\ 0'的字符串分配足够的空间。
您必须使用
int length = strlen(p_string);
int r_it = length - 1;
char* tmp = (char*)malloc(length+1);
由于strlen不会计算\\ 0字符。 因此,如果您不使用length + 1,这将失败:
tmp[last_it] = '\0';
C字符串的长度由终止的空字符确定:AC字符串的长度与字符串开头和终止的空字符之间的字符数一样长(不包括终止的空字符本身)。 http://www.cplusplus.com/reference/cstring/strlen/
顺便说一句。 C99支持半动态数组。 所以你可以尝试一下:
char tmp[length+1];
资料来源: http : //en.wikipedia.org/wiki/Variable-length_array
float read_and_process(int n)
{
float vals[n];
for (int i = 0; i < n; i++)
vals[i] = read_val();
return process(vals, n);
}
检查以下C代码:分配给tmp的内存应为length + 1,如下所示,并且还有许多不必要的变量可以避免。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void reverseString(char *p_string){
int i;
int length = strlen(p_string);
int r_it = length - 1;
char* tmp = (char*)malloc(length+1);
for (i = 0; i != length; i++){
tmp[i] = p_string[r_it--];
}
tmp[i] = '\0';
strcpy(p_string, tmp);
return;
}
int main(){
char str[] = "StackOverflow";
reverseString(str);
printf("%s",str);
return 0;
}
您的方法从根本上没有什么错,只有一些细节。 由于我不确定您是如何发现sizeof(tmp)为32的,因此我将代码修改为以下代码,其中包括一些printf
和一些小的更改:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
void reverseString(char *p_string)
{
size_t length = strlen(p_string);
size_t r_it = length - 1;
char* tmp = (char*)malloc(length+1);
int last_it = 0;
size_t i=0;
printf("strlen(p_string) = %d\n", strlen(p_string));
printf("Before: strlen(tmp) = %d\n", strlen(tmp));
for (i = 0; i != length; i++) {
tmp[i] = p_string[r_it];
r_it--;
last_it++;
}
tmp[last_it] = '\0';
printf("After: strlen(tmp) = %d\n", strlen(tmp));
strcpy(p_string, tmp);
free(tmp);
}
int main()
{
char str[] = "StackOverflow";
reverseString(str);
printf("%s\n", str);
return 0;
}
首先,我删除了所有C ++特定的代码-您现在可以使用gcc
。 运行以下代码将产生以下输出:
sizeof(p_string) = 13
Before: strlen(tmp) = 0
After: strlen(tmp) = 13
wolfrevOkcatS
这是可以预期的strlen
基本上strlen
数字节,直到它到达\\0
字符为止,因此,第一次使用strlen打印大小时,由于我们刚刚分配了内存,因此它返回0。 正如另一个建议的那样,我们必须分配1个额外的字节来将\\0
存储在新字符串中。
一旦完成反向操作,就会将13个字节复制到该内存中,并且第二个strlen
返回预期的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.