有谁知道为什么我一直得到这个seg错误错误? 我正在尝试运行一个程序来定位一个子串"来自"在" src"并替换"中的所有非重叠事件。在src中"到"在输出字符串" dest"。 还有,有人能为我提供测试此案例的正确方法吗?因为我不太确定如何用类型" void" ...(尝试将其作为练习)来显示它
void find_replace(char* src, char* from, char* to, char* dest)
{
int count = 0;
int diff = strlen(to) - strlen(from);
int destlength = strlen(src);
dest = malloc(destlength);
for (int i = 0; i < strlen(src); i++)
{
int index = 0;
while (src[i+index] == from[index] && index < strlen(from)){
index++;
}
if (index == strlen(from)) {
for (int j = 0; j < strlen(to); j++) {
dest[i+j+(count * diff)] = to[j];
}
i += strlen(from) - 1;
count++;
}
else {
dest[i + (count * diff)] = src[i];
}
}
return ;
}
是否足以为测试做到这一点?
int main (int argc, char *argv[])
{
char* dest;
find_replace("hello my name is leeho lim", "leeho lim", "(insert name)" dest);
for (int i = 0; i < strlen(dest); i++)
{
printf("%c", dest[i]);
}
printf("\n");
}
答案 0 :(得分:1)
问题发生的原因是您尝试使用
访问未分配的指针strlen(dest)
在主程序中的for。
原因是你将指针dest
的值发送给函数,而不是指针本身,所以当你在函数内部分配内存时,你实际上没有修改内存地址存储在它外面的指针中。
当您将指针作为函数的参数发送时,您实际在做的是发送存储在该指针中的内存地址,您发送的是存储在指针中的值,而不是指针本身。
如果你想获得字符串的已分配内存地址,你可以让函数返回它,或者你可以声明并发送dest
作为pointer to a pointer。
编辑:正如其他评论指出的那样,你也可以在main()
中执行分配,而不是在你的功能中进行分配。
答案 1 :(得分:0)
您需要对程序进行一些小的调整。
将find_replace
的返回值更改为更改后的字符串的新分配内存。
而不是
void find_replace(char* src, char* from, char* to, char* dest)
使用
char* find_replace(char* src, char* from, char* to)
稍微改变实施。
而不是
dest = malloc(destlength);
使用
char* dest = malloc(destlength);
和
而不是
return;
使用
return dest;
更改您使用该功能的方式。
而不是
char* dest;
find_replace("hello my name is leeho lim", "leeho lim", "(insert name)", dest);
使用
char* dest = find_replace("hello my name is leeho lim", "leeho lim", "(insert name)");
确保释放find_replace
返回的内存。
free(dest);
这是一个完全有效的计划:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* find_replace(char* src, char* from, char* to)
{
int count = 0;
int diff = strlen(to) - strlen(from);
int destlength = strlen(src);
char* dest = malloc(destlength);
for (int i = 0; i < strlen(src); i++)
{
int index = 0;
while (src[i+index] == from[index] && index < strlen(from)){
index++;
}
if (index == strlen(from)) {
for (int j = 0; j < strlen(to); j++) {
dest[i+j+(count * diff)] = to[j];
}
i += strlen(from) - 1;
count++;
}
else {
dest[i + (count * diff)] = src[i];
}
}
return dest;
}
int main (int argc, char *argv[])
{
char* dest = find_replace("hello my name is leeho lim", "leeho lim", "r sahu");
for (int i = 0; i < strlen(dest); i++)
{
printf("%c", dest[i]);
}
free(dest);
printf("\n");
}
更新,以回应OP的评论
如果find_replace
的返回类型必须为void
,则有关如何处理dest
所需内存的几种选项。
在调用函数中为dest
分配内存。
char* dest = malloc(SUFFICIENT_SIZE);
find_replace("hello my name is leeho lim", "leeho lim", "(insert name)", dest);
free(dest);
然后,不需要行
dest = malloc(...);
在find_replace
。
在dest
中为find_replace
分配内存。然后,您需要将指针传递给指针。
void find_replace(char* src, char* from, char* to, char** dest)
并在函数中使用*dest
而不只是dest
。
void find_replace(char* src, char* from, char* to, char** dest)
{
int count = 0;
int diff = strlen(to) - strlen(from);
int destlength = strlen(src);
*dest = malloc(destlength);
for (int i = 0; i < strlen(src); i++)
{
int index = 0;
while (src[i+index] == from[index] && index < strlen(from)){
index++;
}
if (index == strlen(from)) {
for (int j = 0; j < strlen(to); j++) {
(*dest)[i+j+(count * diff)] = to[j];
}
i += strlen(from) - 1;
count++;
}
else {
(*dest)[i + (count * diff)] = src[i];
}
}
return;
}
并更改您的电话find_replace
。
char* dest;
find_replace("hello my name is leeho lim", "leeho lim", "(insert name)", &dest);
答案 2 :(得分:0)
您的(原始)代码存在两个主要问题:
find_replace()
函数将分配的目标缓冲区返回给调用者,并且原则上,问题(1)可以通过两种方式解决。空间可以由调用者分配,并且指向它的指针传递给函数,或者空间可以由函数分配,并且指针返回给调用者。您的原始代码在函数中分配空间,但不会向调用者返回指向它的指针。
该功能最好执行分配,因为满足问题(2)需要对输入进行更彻底的分析,而不是坚持呼叫者执行。考虑一下修改后的代码中会发生什么:
char dest[4];
int canary = 0;
find_replace("aaa", "a", "longer string", dest);
assert(canary == 0);
你最有可能得到一个段错误,可能你得到一个断言失败,也许你得到谁知道什么,因为find_replace()
如果没有写过dest
的结尾就无法完成它的工作,结果未定义。
虽然您已经说过练习要求您的函数没有返回值(即void
),但它仍然可以通过参数列表返回指向目标字符串的指针。您只需将指针传递给dest
指针而不是其值,以便该函数可以更新该值。签名看起来像这样:
void find_replace(const char *src, const char *from, const char *to,
char **dest_p);
(请注意const
,src
和from
的{{1}}个限定符,如果函数是接受字符串文字,则在适当的情况下(如果不是必需的话)是合适的。 )
to
所需的空间量是dest
的长度加一个终结符加上,如果src
长于to
,则长度之间的差异from
和to
字符串的次数乘以from
字符串的出现次数。但是,您可以计算该长度的上限,然后在找出实际使用的空间后缩小分配(如果需要)。例如:
to
实际的替换代码留作练习,毕竟 作业。