C语言:指出程序中的问题总结(一)


    1.下面程序把“hello”这个字符输出,请指出其中的错误:

  void Test()
    {
    char pcArray[10];
    strncpy(pcArray, "hello", 5);
    printf("%s\n", pcArray);
    return;
    }

    问题: 不会直接输出"hello"的,hello的后面还可能有随机值
    原因:因为strncpy的第三个参数指定为5时,只拷贝5个字符即h、e、l、l、o,后面没有拷过去‘\0’,所以当pcArray这个数组的内容是随机值的时候,只覆盖前5个,后面的内容没有找到‘\0’,所以输出的是随机值。
    修改:把5改为6

2.

   #define BUFFER_SIZE 256
    void GetMemory(char **ppszBuf)
    {
    if(NULL==ppszBuf)
    {
    assert(0);
    return;
    }
    ppszBuf = (char *)malloc(BUFFER_SIZE);
    return;
   }
    void Test()
    {
        char *pszBuf = NULL;
        GetMemory(&pszBuf);
        strncpy(pszBuf, "hello world\r\n");
        printf("%s ", pszBuf);
        free(pszBuf);
        return;
    }

  问题:  ①程序执行过程中会发生崩溃   ②程序中有内存泄露
 原因①:GetMemory函数在实现的时候并没有把动态开辟空间的地址存放到pszBuf中,所以strcpy拷贝时,pszBuf依然为 NULL,拷贝失败
  原因②:GetMemory函数在返回之后,动态开辟的内存地址存放在ppszBuf指针变量中,但函数返回之后ppszBuf变量销毁,发生内存泄露
  修改:在GetMemory函数内部,把动态开辟的内存的地址存放在*ppszBuf中

3.请指出下面这段程序中的错误:

    unsigned long FUNC_B(unsigned long ulCount)
    {
        unsigned long ulSum = 0;
        while (0 <= ulCount)
        {
            ulSum += ulCount;
            ulCount;
        }
        return ulSum;
    }

问题: 会出现死循环

原因:因为unsigned long ulCount为无符号数,而无符号数是恒大于0的,即ulCount>=0恒成立,因此会出现死循环

4.下面程序期望输出str=hello world,指出其中错误

    char* GetStr(char *p)
    {
        p = "hello world";
        return p;
    }
    void main()
    {
        char *str = NULL;
        if (NULL != GetStr(str))
        {
            printf("\r\n str=%s", str);
        }
        return;
    }

问题:当GetStr函数返回之后并没有接收它的返回值,所以函数返回之后并没有得到hello world的首字符的地址,str依然为空指针,所以打印时不会打印出来我们想要的内容
修改:让str接收一下GetStr函数的返回值,即把if语句括号里面的改为:NULL !(str= GetStr(str))

5.下面代码中,函数Test执行完毕后,希望输出1,指出错误:

  void VarInit(unsigned char *pucArg)
    {
        *pucArg = 1;
        return;
    }
    void Test()
    {
        unsigned long ulGlobal;
        VarInit((unsigned char*)&ulGlobal);
        printf("%lu", ulGlobal);
        return;
    }

  问题:把unsigned long指针强制转换为unsigned char*指针,而unsigned char*指针解引用后,只能访问四个字节中的一个字节,所以不会输出1

6.指出下面程序错误的地方:

    LONG A()
    {
        if (条件1)
        {
            return;
        }
        return VOS_OK;
    }
    VOID B()
    {
        if (A())
        {
            DoSomeThing1();
        }
        else
        {
            DoSomeThing2();
        }
        return;
    }

错误:LONG A在条件1的时候,返回的值写得不够明确,返回值不可预测

7.找出下面题目中的错误

#define ID_LEN  32
    struct STR_A
    {
        char aucID[ID_LEN];
        int iA;
    };
    struct STR_B
    {
        char *paucID;
        int iB;
    };
    void funcA(struct STR_A stA, struct STR_B *pstB)
    {
        pstB->paucID = stA.aucID;
    }
    void main()
    {
        STR_A stA = { 0 };
        STR_B stB;
        strcpy(stA.aucID, "12345");
        func(stA, &stB);
        printf("%s\n", stB.paucID);
    }

错误:funcA函数在调用的时候,stA采用的是值传递,所以形参stA是实参stA的一份临时拷贝,而stB传参时传的是它的地址,pstB里面存的是stB的地址,函数内部pstB->paucID指向了形参stA里面的一块临时空间,当函数返回之后,形参stA销毁,外面的stB里面的paucID保存好了形参srA里面aucID的地址,这是一个危险的操作,会导致函数返回之后paucID成为野指针。

8.

#define MAX_LEN 2
void ConvertCode(_UC *p_byte, _UC num)
{
    _UL i = 0;
    for (i = 0; i < num; i++)
    {
        p_byte[i] = ((p_byte[i] & 0xF0 >> 4) | ((p_byte[i] & 0x0F << 4);
    }
}
    void main()
    {
        _UC *str = NULL_PTR;
        ConvertCode(str, MAX_LEN);
    }

错误:对空指针的解引用操作,访问内存失败

9.指出下面函数的性能问题

#define MAX_PRAM_LENGTH   10000
typedef struct
    {
    unsigned char ucCommand;
    unsigned short usLength;
    unsigned char Para[MAX_PRAM_LENGTH];
}DEBUG_MSG;
    void PrintDebufMsg(DEBUG_MSG DebugMessage)
    {
        int i;
        printf("\nCommand=%d", DebugMessage.ucCommand);
        for (i = 0; i < DebugMessage.usLength&&i < MAX_PRAM_LENGTH; i++)
        {
            printf("\nPara[%d]=0x%x", i, DebugMessage.Para[i]);
        }
    }

问题:结构体过大,传参时采用值传递的形式,会使得函数在调用过程中,参数压栈的系统开销过大,从而降低程序的性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值