如何将字符串赋值给char*指针?

3
#include <stdio.h>

struct Analysis {
    int lnlen;   
    int arr[2]; 
    char* name;
};

int main()
{
    struct Analysis ana_space[2];
    char *ptr = (void*) &ana_space;

    ana_space[0].lnlen = 0;
    ana_space[0].arr[0] = 1;
    ana_space[0].arr[1] = 2;
    ana_space[0].name = "Peter";

    printf("\n%d\n", *ptr);     // print 0;

    *ptr = 10;                  // how to use memcpy here;

    printf("\n%d\n", *ptr);     // print 10;

    ptr = ptr + sizeof(int);    // advance pointer by int;

    printf("\n%d\n", *ptr);     // print 1;  

    ptr = ptr + 2*sizeof(int);  // advance pointer by 2 ints;

    printf("\n%s\n", *ptr);     // print "Peter"; --------------not work

    //*ptr = "Jim";             // how to assign new name "Jim" into that memory;
    return 0;
}

输出:

0

10

1

(null)

我想使用char *作为指针,通过内存地址获取一些数据,并将值存储到内存中。

对于int和int数组,它可以正常工作,但对于字符串则不行。

如何打印字符串并将新的字符串值存储到内存中?


1
为什么你不使用“.”运算符将值存储到成员中?你是否意识到你所做的事情可能会带来的问题? - 2501
2
你没有考虑结构体内部的填充。 - Dmitri
步骤1:打开编译器警告,快速捕捉像printf("\n%s\n", *ptr);这样的问题。 - chux - Reinstate Monica
3个回答

1
您提供的代码可能会由于填充和类型表示的实现定义而导致未定义的行为。

在此处递增指针ptr后:

ptr = ptr + 2*sizeof(int);

指针ptr指向结构体Analysis的成员name。如果对指针ptr进行解引用,您将获得类型为char的单个字节。该字节不表示指向字符串的指针。
必须将指针ptr转换为指向指向char的指针的指针类型,然后进行解引用,以便获取成员名称的正确和完整值。
结果值是指向字符串“Peter”的指针。

ptr 不一定指向 structname 地址,这取决于成员之间是否有填充。 - R Sahu
@RSahu 显然。 - 2501
ANSI C中的stddef.h中的offsetof()宏可以帮助避免任何关于填充的猜测工作。 - Robert Prévost
@RobertPrévost 我建议您添加一个解释答案。Patrick可能会从那些信息中受益。 - 2501

1

ANSI C中有一个宏叫做offsetof(),可以在stddef.h中找到,它提供了一种更可靠的方法来计算结构体成员的指针偏移量。在这里,我们可以直接获取ana_space[0]中name成员的地址。

ptr = (char*) &ana_space + offsetof(struct Analysis, name);

这消除了填充方面的任何猜测。
然后,必须正确转换此指针才能打印名称的内容。
printf("%s\n", *(char**) ptr);

1
你的方法不具备可移植性。最好使用 offsetof,以确保您可以可靠地指向 struct 成员的地址。
int main()
{
    struct Analysis ana_space[2];
    char *ptr = (void*) &ana_space;

    size_t offset1 = offsetof(struct Analysis, arr);
    size_t offset2 = offsetof(struct Analysis, name);

    ana_space[0].lnlen = 0;
    ana_space[0].arr[0] = 1;
    ana_space[0].arr[1] = 2;
    ana_space[0].name = "Peter";

    // advance pointer to point to arr.
    ptr = ptr + offset1;

    // advance pointer to point to name
    ptr = ptr + (offset2-offset1);

    // Cast the pointer appropriately before dereferencing.
    printf("\n%s\n", *(char**)ptr); 

    // how to assign new name "Jim" into that memory;
    *(char**)ptr = "Jim";
    printf("\n%s\n", *(char**)ptr);

    return 0;
}

您使用了以下内容:
printf("\n%d\n", *ptr);     // print 0;

*ptr = 10;                  // how to use memcpy here;

printf("\n%d\n", *ptr);     // print 10;

期望输出有缺陷。 它仅适用于小端系统。 我建议使用:

printf("\n%d\n", *(int*)ptr);

*(int*)ptr = 10;

printf("\n%d\n", *(int*)ptr);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接