初学者C:为什么两个变量的初始化方式不同

时间:2014-09-18 21:25:58

标签: c memory

我有以下无法成功运行的代码。 src被分配了一个内存地址但是dest没有。我正在使用Xcode 5进行命令行开发

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

int main ()
{
    char* src;
    char* dest;

    memcpy(src,  "This is source", 15);
    memcpy(dest, "This is destination", 20);

    strcat(dest, src);

    printf("Final destination string : |%s|", dest);

    return(0);
}

声明后,src的值为“”并且有一个地址,但dest为NULL。我知道这是一个愚蠢的问题,但需要一些帮助来解决这个问题。

更新 经过一系列调查后,我开始知道我需要在memcpy之前初始化指针的空间,尽管Xcode没有提供我可以轻易找到的有用警告或异常。

正确的用法是使用malloc初始化空间然后执行memcpy。

char* src;
char* dest;
src = malloc(sizeof(char)*15);
dest = malloc(sizeof(char)*34);

memcpy(src,  "This is source", 15);
memcpy(dest, "This is destination", 20);

或者我们也可以使用char数组并在dest上留下足够的空间。

char src[15];
char dest[34];

memcpy(src,  "This is source", 15);
memcpy(dest, "This is destination", 20);

4 个答案:

答案 0 :(得分:1)

您既没有初始化src也没有初始化,因此不清楚您要复制字符串文字的位置。 该程序有不确定的行为。

你可以使用数组做同样的事情。例如

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

int main( void )
{
    char src[] = "This is source";
    char dest[34] = "This is destination";


    strcat( dest, src );

    printf( "Final destination string : |%s|", dest );

    return 0;
}

使用指针的另一种方法

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

int main( void )
{
    const char *s1 = "This is source";
    const char *s2 = "This is destination";

    char *dest = malloc( strlen( s1 ) + strlen( s2 ) + 1 );

    strcat( strcpy( dest, s2 ), s1 );

    printf( "Final destination string : |%s|", dest );

    free( dest );

    return 0;
}

答案 1 :(得分:1)

您的代码调用未定义的行为。您在初始化之前使用自动存储变量srcdest的值。

你写了

  

“为src分配了一个内存地址”

这个假设错误!(大感叹号)。变量未初始化,当您以这种方式使用时,任何事情都可能发生。期间,没有讨论。

在C程序中有两种变量:

  • 静态存储,这意味着变量使用的存储是在链接时确定的。全局变量和具有static初始值设定项的函数变量都属于这种类型。静态范围变量在程序加载时初始化为0.

  • 自动存储,这意味着当程序执行时,变量的存储就会存在。

除此之外,C对象也可以是动态存储,由malloc或其亲属分配。

这对你意味着什么? 您必须初始化这些变量。如果将它们放在静态存储中,它们会被初始化为0,这对于指针来说是一个非常好的值,但是取消引用它,这是您的代码所做的,是不允许的。因此,您必须将它们初始化为兼容对象(=内存区域)的地址,该对象与指针的使用相匹配。

答案 2 :(得分:0)

如果使用指针,在使用memcpy之前,必须使用malloc(或其他内存分配例程)显式保留或分配用于存储要复制的字节的空间:

char *src = NULL;

/* add 1 byte for '\0' string terminator... */
src = malloc(strlen("This is source") + 1); 
if (!src) {
    fprintf(stderr, "Error: Could not reserve memory for src pointer\n");
    exit(EXIT_FAILURE);
}

/* copy over bytes (including terminator byte)... */
memcpy(src, "This is source", 15);

/* do stuff with 'src'... */

/* don't forget to free 'src' when you are done with it... */
free(src);

使用strcat时,还应为目标指针dest分配足够的空间来存储连接的终止结果。上面的代码片段应提供有关如何执行此操作的充分提示。

答案 3 :(得分:-2)

您需要使用malloc或将指针设置为现有数组的内存: 你需要这样做是因为你的指针现在正指向你记忆的随机区域,你可以确定的方式崩溃或一般系统不稳定 即:

    src=malloc(80);

    char mem1[160];
    src=mem1;
    dst=mem1+80;

//或

    char mem2[89];
    dst=mem2;