You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免strcmp与NULL比较?C语言程序段错误求助

问题分析与修复

导致段错误的核心原因

你的程序出现段错误不止是strcmp的问题,主要有以下几个关键错误:

1. 字符串常量不可修改

你把marca和aux指向了字符串常量" ":

marca=" ";
aux=" ";        

字符串常量存在只读内存区域,后续用scanf("%s",marca)或者strcpy(marca, aux)修改它们的内容,会直接触发内存访问错误,导致段错误。

2. strcmp传入NULL指针

你的marcas数组初始化时用了'\0',对于char*类型的数组元素,'\0'会被解析为NULL指针(字符'\0'的ASCII值是0,和空指针的地址值一致)。当循环遍历到这些NULL元素时,strcmp(marcas[i], marca)把NULL作为参数传入,而strcmp要求两个参数都是指向有效C字符串的指针,传入NULL会直接触发段错误。

3. 错误修改字符串常量

marcas前5个元素指向字符串常量,你直接用strcpy(marcas[i], marca)修改这些常量的内容,同样会触发只读内存的访问错误。


修复后的代码

调整内存分配方式,给marca和aux分配可写空间,同时修正marcas的初始化和插入逻辑:

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

int main ()
{
    // 用NULL明确表示空指针,替代原代码的'\0'
    char *marcas[7] = {"Alfa Romeo", "Fiat", "Ford", "Lancia", "Renault", NULL, NULL};
    // 分配可写缓冲区存储输入和临时数据
    char marca[50], aux[50];
    int i;
    int cont=5;
    
    for(i=0;i<cont;i++)
        printf("%s\n",marcas[i]);
        
    while (cont<7){
        printf("Ingrese la marca que desee agregar a la lista.\n");
        // 限制输入长度,避免缓冲区溢出
        scanf("%49s", marca);
        printf("Gracias. Ud. quiere agregar la marca: %s.\n", marca);
        
        i=0;
        // 先检查marcas[i]非空,再调用strcmp
        while(i < cont && marcas[i] != NULL && strcmp(marcas[i], marca) < 0){
            i++;
            printf("Moviendo puntero.\n");
        }
        printf("Termine de mover.\n");
        
        if (i < cont){
            // 从后往前移动元素,避免数据覆盖
            for(int j = cont; j > i; j--){
                marcas[j] = marcas[j-1];
            }
        }
        // 为新品牌分配内存并拷贝内容
        marcas[i] = malloc(strlen(marca) + 1);
        strcpy(marcas[i], marca);
        
        cont++;
        printf("%s tiene que ir en la posicion %d\n", marca, i);
        
        for(i=0;i<cont;i++)
            printf("%s\n", marcas[i]);
        printf("La marca ingresada última a la lista:%s\n", marca);
    }
    
    for(i=0;i<7;i++){
        if(marcas[i] != NULL)
            printf("%s\n", marcas[i]);
    }
    
    // 释放动态分配的内存,避免内存泄漏
    for(i=0;i<7;i++){
        if(marcas[i] != NULL)
            free(marcas[i]);
    }
    return 0;
}

如何避免strcmp与NULL比较

要彻底避免这种问题,需要在调用strcmp前先检查参数有效性:

  • 每次调用strcmp(a, b)前,先判断a != NULL且b != NULL
  • 如果其中一个是NULL,单独处理(比如把NULL视为小于任何有效字符串,或者直接报错)

可以封装一个安全的字符串比较函数:

int safe_strcmp(const char *a, const char *b) {
    if (a == NULL && b == NULL) return 0;
    if (a == NULL) return -1; // NULL视为比任何字符串小
    if (b == NULL) return 1;
    return strcmp(a, b);
}

之后用safe_strcmp替代原生strcmp,就不会因为传入NULL触发段错误了。

内容的提问来源于stack exchange,提问作者Andrea Graf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 03:15:40