C语言基础知识点 (十五) 结构体中的字符数组和字符指针

文章讨论了在C语言中,如何正确使用字符数组和字符指针存储字符串,强调了结构体中使用数组类型而非指针的重要性,以及如何避免内存访问错误和内存泄漏。同时提到了使用`malloc`动态分配内存和安全输入函数`fgets`的应用。
摘要由CSDN通过智能技术生成
#include <stdio.h>
#include <string.h>

#define LEN 20

struct names
{

    char first[LEN];
    char last[LEN];
};

struct pnames
{

    char *first;
    char *last;
};
int main()
{
    struct names veeo = {"Veeo", "<NAME>"};

    struct pnames veeo1 = {"GZHU", "GHK"};

    scanf("%s", veeo.first); // char first[LEN];无问题
   // scanf("%s", veeo1.first); // char *first; 出问题
    printf("%s and%s\n", veeo.first, veeo1.first);
    printf("%p,%p", &veeo.first, &veeo1.first);
    return 0;
}

今天在学习字符数组和字符指针来储存字符串时发现

可以使用指向char的指针来代替字符数组,但是通过字符指针来存储的字符串并没有分配内存空间来存储字符串,使用 scanf 向这些字段中读取字符串时可能会导致内存访问错误或者段错误。

具体来说,struct pnames 中的 firstlast 字段被定义为指针类型 char *,而不是数组类型,因此它们并没有被分配内存空间来存储字符串。当你尝试使用 scanf 读取字符串到这些字段时,会涉及到未分配的内存地址,从而导致程序运行时错误。

相反,struct names 中的 firstlast 字段被定义为数组类型 char [LEN],这意味着它们有固定大小的内存空间来存储字符串。因此,使用 scanf 来向这些字段中读取字符串是安全的。

为了修正这个问题,你可以考虑将 struct pnames 中的 firstlast 字段也改为数组类型 char [LEN],以确保有足够的内存空间来存储字符串。另外,当使用 scanf 读取字符串时,最好使用安全的输入函数,如 fgets,并且要确保输入的字符串不会超出预分配的内存空间。

这里我补充一下,其实使用指针变量也是可以的,也就是使用malloc()这个函数

malloc(LEN * sizeof(char))veeo1.firstveeo1.last分配了LENchar类型大小的内存空间。这样就为这两个指针分配了足够的内存来存储字符串。在使用完这些内存后,通过调用free函数释放分配的内存,以避免内存泄漏问题。

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

#define LEN 20

struct names
{
    char first[LEN];
    char last[LEN];
};

struct pnames
{
    char *first;
    char *last;
};

int main()
{
    struct names veeo = {"Veeo", "<NAME>"};
    struct pnames veeo1;

    veeo1.first = (char *)malloc(LEN * sizeof(char));
    veeo1.last = (char *)malloc(LEN * sizeof(char));

    if (veeo1.first == NULL || veeo1.last == NULL)
    {
        printf("Memory allocation failed\n");
        return 1;
    }

    scanf("%19s", veeo.first);
    scanf("%19s", veeo1.first);

    printf("%s and %s\n", veeo.first, veeo1.first);
    printf("%p, %p", &veeo.first, &veeo1.first);

    free(veeo1.first);
    free(veeo1.last);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值