如何使用 dynamic-memory-allocation 修复此程序中 c 中的总线错误?

How do i fix an bus error in c in this program with dynamic-memory-allocation?

提问人:Duarte Pereira 提问时间:4/25/2023 最后编辑:Duarte Pereira 更新时间:4/25/2023 访问量:85

问:

为什么我收到总线错误?

我正在制作一个简单的程序来缩写中间名,例如,我们有 Artur José Bastos Costa,它应该打印“Artur JB Costa”。

这是我的代码:在此处输入图像描述 在此处输入图像描述

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* abrevia(char full_name[]){
    int numNames = 0, i = 0;
    char* abbreviation = (char*) malloc(strlen(full_name) * sizeof(char));
    char* name = strtok(full_name, " ");
    strcpy(abbreviation, name);
    strncat(abbreviation, " ", 1);
    while (name != NULL){
        numNames++;
        name = strtok(NULL, " "); 
    }

    char* nomeCopy = (char*) malloc(strlen(full_name) * sizeof(char));
    strcpy(nomeCopy, full_name);
    char* name2 = strtok(nomeCopy, " ");
    while (name2 != NULL){
        if (i != numNames -1){
            strncat(abbreviation, &name2[0], 1);
            abbreviation[strlen(abbreviation)] = '.';
            abbreviation[strlen(abbreviation)] = ' ';
        }
        else {
            strcat(abbreviation, name2);
        }
        name2 = strtok(NULL, " ");
        i++;
    }
    free(nomeCopy);
    return abbreviation;
}

int main(){
    char* abr = abrevia("Artur José Bastos Costa");
    printf("%s", abr);
    free(abr);
    return 0;
}

首先我没有复制full_name,但我尝试这样做,因为我使用了两次 strtok,第一次没有更多的代币,所以我很难在第二个循环中它会因此崩溃。但我无法修复它。 对不起,我的英语不是我的第一语言

c malloc 动态内存分配 总线错误

评论

3赞 teapot418 4/25/2023
nomeCopy = (char*) malloc(strlen(full_name) * sizeof(char));那太少了,别忘了终止零字符
2赞 teapot418 4/25/2023
在缩写不再以 null 结尾(您已覆盖终止字符)并且后续行为未定义之后。请改用 str(n)cat。abbreviation[strlen(abbreviation)] = '.';strlen(abbreviation)
0赞 Allan Wind 4/25/2023
重新格式化了代码以提高可读性。不要投射 .sizeof(char) 定义为 1。void *
0赞 Allan Wind 4/25/2023
首选迭代器的循环。forwhile
0赞 Duarte Pereira 4/25/2023
@teapot418那我应该怎么做呢?

答:

1赞 Allan Wind 4/25/2023 #1
  1. 总线错误/段错误是由于将只读字符串文字传递给但修改了它的第一个参数。您可以像这样传递数组:abrevia()strtok()
    char *abr = abrevia((char []) { "Artur José Bastos Costa"});

或者更好的是,如果你想使用(而不是)将字符串复制到数组中。这允许您使输入成为指向常量值的指针。strtok()strpbrk()abrevia()

  1. malloc(strlen(full_name))1 个字节太小。

  2. 首选传递变量而不是 .减少代码重复。定义为 1,所以我就把它省略了。sizeof()sizeof(char)

  3. 不要将 from .void *malloc()

  4. 您不会对第二个中间名执行任何操作。

基本思想是将第一个和最后一个令牌作为特殊情况进行处理。要确定它是否是最后一个令牌,您需要进行 1 个令牌展望:

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *abrevia(const char *full_name){
    char *full_name2 = strdup(full_name);
    char *name = strtok(full_name2, " ");
    if(!name) {
        free(full_name2);
        return NULL;
    }
    char *abbreviation = malloc(strlen(full_name2) + 1);
    strcpy(abbreviation, name);
    name = strtok(NULL, " ");
    for(;;) {
        char *name2 = strtok(NULL, " ");
        if(!name2)
            break;
        strcat(abbreviation, " ");
        strncat(abbreviation, name, 1);
        strcat(abbreviation, ".");
        name = name2;
    }
    if(name) {
        strcat(abbreviation, " ");
        strcat(abbreviation, name);
    }
    free(full_name2);
    return abbreviation;
}

int main(){
    char *abr = abrevia("Artur José Bastos Costa");
    printf("%s\n", abr);
    free(abr);
    return 0;
}

这是输出:

Artur J. B. Costa

评论

0赞 Duarte Pereira 4/25/2023
仍然行不通
0赞 Duarte Pereira 4/25/2023
ty,它不再给我总线错误,现在我只需要修复其余的