C 基于字符串字符大小为字符串分配内存空间与整个字符串大小之间的差异

C 基于字符串字符大小为字符串分配内存空间与整个字符串大小之间的差异,c,C,当我们为字符串分配内存空间时,以下两种方法是否给出相同的结果 char *s = "abc"; char *st1 = (char *)malloc(sizeof(char)*strlen(s)); char *st2 = (char *)malloc(sizeof(s)); 换句话说,基于字符大小分配内存是否与基于整个字符串大小分配内存的结果相同 如果我使用后一种方法,我是否仍然可以逐个字符地向该内存空间添加以下内容: *st = 'a'; st++; *st = 'b'

当我们为字符串分配内存空间时,以下两种方法是否给出相同的结果

char *s = "abc";
char *st1 = (char *)malloc(sizeof(char)*strlen(s));
char *st2 = (char *)malloc(sizeof(s));
换句话说,基于字符大小分配内存是否与基于整个字符串大小分配内存的结果相同

如果我使用后一种方法,我是否仍然可以逐个字符地向该内存空间添加以下内容:

*st = 'a';
st++;
*st = 'b';

或者我现在必须立即添加整个字符串吗?

让我们看看是否无法让您澄清您的问题以及如何分配(和重新分配)存储。首先,当您声明:

char *s = "abc";
您已经声明了一个指向
char
s
的指针,并且已经将字符串Literal
“abc”
的起始地址分配给了指针
s
。无论何时尝试在
a_指针上使用
sizeof()
,都会得到
sizeof(a_指针)
,在x86_64上通常是8字节(或x86上是4字节,等等)

如果您采用
sizeof(“abc”)
您采用的是大小为4的字符数组的大小(例如
{'a','b','c','\0'}
),因为字符串文字是一个
char
数组,初始化为保存字符串
“abc”
(包括nul终止字符)。还要注意的是,在几乎所有系统上,字符串文字都是在只读内存中创建的,不能修改,它是不可变的

如果要分配存储以保存字符串“abc”
的副本,则必须分配
strlen(“abc”)+1
字符(nul终止字符的+1'\0'--即ASCII
0
,请参阅

每当您分配内存时,您对分配的任何内存块都有两项责任:(1)始终保留指向内存块起始地址的指针,这样,(2)当不再需要时,它可以被释放。因此,如果您为
char*st=malloc(len+1)分配;
characters,您不希望使用指针
st
(例如,no
st++
)进行迭代。相反,请声明第二个指针
char*p=st;
,您可以自由地使用
p
进行迭代

另外,在C中,不需要强制转换malloc的返回,这是不必要的。请参阅:

如果要添加到分配中,请使用
realloc()
,这将为您创建一个新的内存块,并将现有的内存块复制到其中。使用
realloc()
时,您始终使用临时指针重新分配(例如,不要
st=realloc(st,new_size);
),因为如果
realloc()
失败,它返回
NULL
,如果您将其分配给指针
st
,则您刚刚丢失了原始指针并造成内存泄漏。相反,请使用临时指针,例如
void*tmp=realloc(st,new_size);
然后验证
realloc()
在分配
st=tmp;

现在,通过阅读示例中要用到的行之间的内容,下面展示了如何做到这一点,跟踪分配的
内存量和使用的
内存量。然后,当
使用==分配的
时,重新分配更多内存(记住确保nul终止字符有+1字节可用

一个简单的例子是:

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

#define THISMANY 23

int main (void) {

    char *s = "abc", *st, *p;               /* string literal and pointer st */
    size_t  len = strlen(s),                /* length of s */
            allocated = len + 1,            /* number of bytes in new block allocated */
            used = 0;                       /* number of bytes in new block used */
    
    st = malloc (allocated);                /* allocate storage for copy of s */
    p = st;                                 /* pointer to allocate, preserve st */
    
    if (!st) {                              /* validate EVERY allocation */
        perror ("malloc-st");
        return 1;
    }
    
    for (int i = 0; s[i]; i++) {            /* copy s to new block of memory */
        *p++ = s[i];                        /* (could use strcpy) */
        used++;                             /* advance counter */
    }
    *p = 0;                                 /* nul-terminate copy */
    
    for (size_t i = 0; i < THISMANY; i++) { /* loop THISMANY times */
        if (used + 1 == allocated) {        /* check if realloc needed (remember '\0') */
            /* always realloc using temporary pointer */
            void *tmp = realloc (st, 2 * allocated);    /* realloc 2X current */
            if (!tmp) {                     /* validate EVERY reallocation */
                perror ("realloc-st");
                break;                      /* don't exit, original st stil valid */
            }
            st = tmp;                       /* assign reallocated block to st */
            allocated *= 2;                 /* update allocated amount */
        }
        *p++ = 'a' + used++;                /* assign new char, increment used */
    }
    *p = 0;                                 /* nul-terminate */
    
    printf ("result st  : %s\n"             /* output final string, length, allocated */
            "length st  : %zu bytes\n"
            "final size : %zu bytes\n", st, strlen(st), allocated);
    
    free (st);      /* don't forget to free what you have allocated */
}
仔细看看,如果这回答了你的问题,请告诉我,如果没有,请留下评论,我很乐意进一步提供帮助


如果您对指针是什么仍然不确定,并且想要了解更多信息,这里有一些链接,提供了一些关于指针的基本讨论,可能会有所帮助。并且(忽略标题,答案讨论指针的基本知识)

否。
sizeof(s)
是sizeof
a_指针
strlen(s)
将是字符串文本(
3
)中的字符数。如图所示,您可以迭代通用指针
st
。您只需跟踪使用的字符数,并在用完时跟踪
realloc()
。您应该打印出sizeof
sizeof(s)的值
是指针的大小,而不是字符串的大小。另外,在分配字符串时,不要忘记分配以终止空字符。