c - 手动编码的连接函数错误(分段错误(核心转储))
问题描述
我正在尝试创建一个函数,将 , 和 连接a
到b
一个c
名为result
.
#include <stdio.h>
const char* concat(char* a, char* b, char* c) {
char *result; // Concatenated variable (A + B)
int i; // Index of A, B and C
int ir; // Index of result
// result = A
for(i=0; a[i] != '\0'; i++) {
ir = i;
result[ir] = a[i];
} // → for
// result = A + B
ir++;
for(i = 0; b[i] != '\0'; i++) {
if (i == 0)
ir = ir + i;
result[ir] = b[i];
} // → for
// result = A + B + C
ir++;
for(i = 0; c[i] != '\0'; i++) {
ir = ir + i;
result[ir] = c[i];
} // → for
return result;
} // → concatenate()
但是当我使用以下块编译和运行时,它会导致Segmentation fault (core dumped)
错误。我已经搜索过它(什么是分段错误?)但没有得到洞察力。我究竟做错了什么?
int main() {
char* a = "1234567";
char* b = "abcdefg";
char* c = "_______";
printf("%s", concat(a, b, c));
}
错误:
Segmentation fault (core dumped)
解决方案
显示的代码试图将数据存储到未定义的缓冲区 ( result
) 中,这并非不合规矩。有些人必须通过传入有界输出缓冲区来分配空间,无论是您的函数还是调用者。
使用分配内存机制,您必须提前获取所有字符串的完整大小,以便您可以一次分配完整的块。分配完整块后,一次复制一个字符串。
char *concat3(const char *a, const char *b, const char *c)
{
// get the required size in advance
size_t n = 0;
for (const char *ap = a; *ap; ap++) n++;
for (const char *bp = b; *bp; bp++) n++;
for (const char *cp = c; *cp; cp++) n++;
char *result = malloc(n + 1);
char *op = result;
while (*op = *a++) op++;
while (*op = *b++) op++;
while (*op = *c++) op++;
return result;
}
另请注意,参数const char *
不是char *
为了确保每个人都知道concat3
——我更改了名称——不会写入这些输入缓冲区。
但是,返回值不能是const
因为你必须释放它,我希望你记得这样做。
编辑我添加了一个不同的版本,它写入有界输出缓冲区,因此函数中不需要内存分配,因为调用者负责它:
char *concat(char *obuf, size_t osize, const char *a, const char *b, const char *c)
{
char *obuf_save = obuf;
const char *obuf_max = obuf + osize - 1;
while (obuf < obuf_max && (*obuf = *a++)) obuf++;
while (obuf < obuf_max && (*obuf = *b++)) obuf++;
while (obuf < obuf_max && (*obuf = *c++)) obuf++;
*obuf = 0;
return obuf_save;
}
关键部分是传递输出缓冲区和大小,它保证不会覆盖缓冲区的末尾。
关键缺点:您无法判断它是否被截断。如果这很重要,取决于您的应用程序。
推荐阅读
- html - 当我悬停它时,按钮移动了一点
- python - 当我们在 Django 中传递命令 python manage.py createsuperuser 时,后台会发生什么?
- python - 在 Python 中的子数据集中格式化日期时间
- laravel - Laravel 7.x config:cache 后视图相关异常
- ruby-on-rails - Rails更新后未定义的局部变量或方法`arel_table'
- python-3.x - FB Prophet 次日数据 - 捕获趋势,但未捕获每小时季节性
- r - 在论文中报告 Moran's I 测试结果
- spring - 无法解析spring webmvc项目中的符号@Configuration
- javascript - JQgrid addJSONData 不是一个函数
- python - pip install indexer 和 python3 -m pip install indexer 出错