我只是想让你问这个代码我做错了什么。 我写了一个函数,在参数中取一个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 ++而不经常使用像malloc / free / strcpy这样的C函数... 在这里,我的问题是,当我为我的临时字符分配内存时,我在这种情况下调用了mallec(length)长度= 13,char = 1个字节所以它应该为13个字符分配内存是对的吗?
问题是分配比需要更多的空间,所以我需要在我的strcpy_s之前使用'\ 0',如果没有它会中断。
我在某处犯了错误吗? 此外,当我调用free(tmp)时,它也会断开并说堆损坏,但在此之前我没有释放内存。
感谢您的帮助!
答案 0 :(得分:2)
我拿了原始代码并在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'
答案 1 :(得分:1)
您必须使用
int length = strlen(p_string);
int r_it = length - 1;
char* tmp = (char*)malloc(length+1);
因为strlen不计算\ 0字符。因此,如果您不使用长度+ 1:
,这将失败tmp[last_it] = '\0';
C字符串的长度由终止确定 null-character:C字符串与字符数一样长 在字符串的开头和终止的空字符之间 (不包括终止空字符本身)。 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);
}
答案 2 :(得分:0)
检查以下C代码: 分配给tmp的内存应该是长度+ 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;
}
答案 3 :(得分: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
基本上计算字节直到它到达\0
字符,因此我们第一次使用strlen打印大小时,它返回0,因为我们刚刚分配了内存。正如另一张海报建议的那样,我们必须分配1个额外的字节来将\0
存储在我们的新字符串中。
反向完成后,13个字节将被复制到此内存,第二个strlen
将返回预期答案。