在开始之前,我应该说我已经看到了一些关于这个主题的帖子(比如this one,但是我仍然遗漏了一些东西我对C很陌生,所以请容忍我。我试图构造一个函数,将字符串从一个指针位置复制到另一个指针位置。

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

void astrncpy(char **base, char *copyme){

    printf("Copying '%s' into a location currently featuring the following string: '%s'\n", copyme,*base);
    printf("The location of our string to be copied (%s) is %d.\n", copyme, &copyme);
    printf("The location of our string to be replaced (%s) is %d.\n", *base, base);

    //Declare string length variable
    int new_len=strlen(copyme);
    printf("Calculating new length for replaced memory allocation (%d).\n",new_len);

    //Reallocate pointer array
    *base=realloc(*base,sizeof(char)*new_len+1);
    printf("Reallocating memory allocation.\n");

    //Copy copyme content to base string location
    strncpy(*base,copyme,new_len);

    printf("The string at location %d is now %s\n", base, *base);

}

void main(){

    //Declare iterator
    int i;

    //Generate strings
    char first_lit[]="Fortran?";
    char second[]="Now that's a name I've not heard in a long time.";

    //Convert first string to array (so we can get at the pointer to the strings pointer)
    char **first; //Declare pointer to pointer array that represents the first string
    first=malloc(strlen(first_lit)*sizeof(char)); //Allocate space for the pointer array
    *first=first_lit; //Assign values to the pointer locations

    //Copy copyme into base
    astrncpy(first,second);
}

当我试图在astrncpy()内重新分配时,核心转储。据我所知,如果指针数组不是空的,或者不是malloc()的乘积,就会发生这种情况我觉得我没有不及格任何关于正在发生的事情的指导都是值得赞赏的。
对我构建输入的洞察的加分我花了很多时间来尝试确定*base参数的可接受输入是什么(注意**base的两个参数都在我正在处理的文本中给出)但是,我不清楚为什么我不能用astrncpy()而不是构造first_lit字符串仍然是数组,不是吗?再次感谢您的帮助。
更新:我花了一段时间来做我实际得到的工作,但回到这里,我不能动摇的想法,声明修改在下面的回应是没有必要的。(这是因为文本中还没有涉及到它们。)无论如何,我仍然会检查解决方案,因为它在多个方面都很有用。但应注意的是,以下方法也适用:
/*Program demonstrates string manipulation operations*/

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

void astrncpy(char **base, char *copyme){

    printf("\nWe are inside the function, astrncpy.\n");
    printf("\nCopying '%s' (*copyme) into a location currently featuring the following string: '%s' (**base)\n", copyme,*base);
    printf("The location of our string to be copied (%s) is %p.\n", copyme, &copyme);
    printf("The location of our string to be replaced (%s) is %p.\n", *base, base);

    //Declare string length variable
    size_t new_len=strlen(copyme);
    printf("Calculating new length for replaced memory allocation (%d).\n",new_len);

    //Reallocate pointer array
    printf("Reallocating memory block associated with base string to be replaced.\n");
    *base=realloc(*base,sizeof(char)*(new_len+1));


    //Copy copyme content to base string location
    strncpy(*base,copyme,new_len);

    printf("The string at location %p is now %s\n", base, *base);

}

void main(){

    //Declare iterator
    int i;

    //Generate strings
    char first_lit[]="Fortran?";
    char second[]="Now that's a name I've not heard in a long time.";
    //int testint=5;

    //Capture elements of first_lit in pointer array (so we can get at the pointer to the strings pointer)
    char *first; //Declare pointer to pointer array that represents the first string
    first=malloc((strlen(first_lit)+1)*sizeof(char)); //Allocate space for the pointer array
    strncpy(first,first_lit,strlen(first_lit)); //Assign values to the pointer locations

    //Copy copyme into base
    printf("Initiating copy operation...\n");
    astrncpy(&first,second);
}

最佳答案

看这些陈述

first=malloc(strlen(first_lit)*sizeof(char)); //Allocate space for the pointer array
*first=first_lit; //Assign values to the pointer locations

似乎您认为可以将数组与其他数组一起分配。
这是一个错误的假设。只能将一个数组的元素复制到另一个数组中。
还要考虑到您将函数命名为
astrncpy
    ^^

但通常这些中间带有n的函数有一个size_t类型的参数。函数没有这样的参数所以最好这样命名
astrcpy

函数名中间没有n
通常字符串函数返回指向目标字符串的指针。
你的意思是
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char * astrcpy( char **base, const char *copyme )
{
    printf( "Copying '%s' into a location currently featuring the following string: '%s'\n", copyme,*base );
    printf( "The location of our string to be copied (%s) is %p.\n", copyme, ( const void * )copyme );
    printf( "The location of our string to be replaced (%s) is %p.\n", *base,  ( void * )*base );

    //Declare string length variable
    size_t new_len = strlen( copyme );
    printf("Calculating new length for replaced memory allocation (%zu).\n", new_len );

    //Reallocate pointer array
    printf("Reallocating memory allocation.\n");

    char *tmp;
    if ( ( tmp = realloc( *base, sizeof( char ) * ( new_len + 1 ) ) ) != NULL )
    {
        *base = tmp;

        //Copy copyme content to base string location
        strcpy( *base, copyme );

        printf( "The string at location %p is now %s\n", ( void * )*base, *base );
    }

    return tmp;
}

int main( void )
{
    //Generate strings
    char first_lit[] = "Fortran?";
    char second[] = "Now that's a name I've not heard in a long time.";

    //Convert first string to array (so we can get at the pointer to the strings pointer)
    char *first; //Declare pointer to pointer array that represents the first string

    first = malloc( ( strlen( first_lit ) + 1 ) * sizeof( char ) ); //Allocate space for the pointer array
    strcpy( first, first_lit ); //Assign values to the pointer locations

    //Copy copyme into base
    if ( astrcpy( &first, second ) ) puts( first );

    free( first );
}

程序输出是
Copying 'Now that's a name I've not heard in a long time.' into a location currently featuring the following string: 'Fortran?'
The location of our string to be copied (Now that's a name I've not heard in a long time.) is 0x7ffe4b3d23d0.
The location of our string to be replaced (Fortran?) is 0x6da010.
Calculating new length for replaced memory allocation (48).
Reallocating memory allocation.
The string at location 0x6da010 is now Now that's a name I've not heard in a long time.
Now that's a name I've not heard in a long time.

有趣的是,函数realloc没有改变内存的初始地址只是把它放大了
重新分配之前
The location of our string to be replaced (Fortran?) is 0x6da010.

在重新分配之后
The string at location 0x6da010 is now Now that's a name I've not heard in a long time.

地址相同0x6da010
关于这个问题
但是,我不清楚为什么我不能在第一时间到达那里
而不是必须先建造
然后,不能移动具有静态或自动存储持续时间的数组。您只能重新分配动态分配的内存并在其中复制一个数组。
因此您不能重新分配first_lit的内存您可以动态分配内存并复制数组的元素,然后重新分配这个动态分配的内存。

10-04 22:22