如何使用动态内存分配修复此程序中 c 中的总线错误?

问题描述 投票:0回答:1

为什么我收到总线错误?

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

这是我的代码: enter image description here enter image description here

#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;
}

首先我没有复制全名,但我尝试这样做是因为我使用了两次 strtok 并且第一次没有更多的标记,所以我认为在第二个循环中它会因此而崩溃。但我无法修复它。 对不起,我的英语不是我的母语

c malloc dynamic-memory-allocation bus-error
1个回答
0
投票
  1. 段错误是由于将只读字符串文字传递给
    abrevia()
    但是
    strtok()
    修改了它的第一个参数。
    char *abr = abrevia((char []) { "Artur José Bastos Costa"});

或者更好的是让

abrevia()
将字符串复制到一个数组中。这允许您使输入成为一个指向常量值的指针。

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

  2. 你不对第二个中间名做任何事情。

基本思想是将第一个和最后一个标记作为特殊情况处理。要确定它是否是最后一个令牌,您需要进行 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)
        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
© www.soinside.com 2019 - 2024. All rights reserved.