为C中的递归strcat()函数分配内存



我正试图使用其他问题中的提示构建一个上下文无关的语法符号器,但我在分配足够的内存时遇到了问题。

基本代码:

char * print_S ( )
{
    int los = zero_or_one();
    if ( los == 1 )
            return "1";
    else
            return strcat( print_A(), print_A() );
}
char * print_A ( )
{
    int los = zero_or_one();
    if ( los == 1 )
            return "0";
    else
            return strcat( print_S(), print_S() );
}

当los=0时返回分段错误。
然后我尝试了为字符串分配内存,然后将其传递给函数,但仍然没有成功:

char * out = (char *) malloc( 100 * sizeof(*out) );
printf("%sn", print_S( out ) );

char * print_S ( char * out )
{
    int los = zero_or_one();
    if ( los == 1 ) {
        strcpy (out, "1");
        return out;
    } else {
        return strcat( print_A(out), print_A(out) );
    }
}
char * print_A ( char * out )
{
    int los = zero_or_one();
    if ( los == 1 ) {
        strcpy (out, "0");
        return out;
    } else {
        return strcat( print_S(out), print_S(out) );
    }
}

什么是正确的方法?感谢

在给定另一个问题的上下文的情况下,我认为您应该安排对函数的初始调用,以给定一个由100个字符组成的数组的开头和结尾。当您递归地向下工作时,您可以适当地增加传递给其他函数的开始指针。

这个代码对我有效:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* One of these is sufficient; symmetry requires both */
static char *print_S(char *dst, char *end);
static char *print_A(char *dst, char *end);
static int zero_or_one(void)
{
    int rv = rand() % 2;
    return rv;
}
static char *print_S(char *dst, char *end)
{
    assert(dst <= end);
    if (dst < end)
    {
        if (zero_or_one() == 0)
            *dst++ = '0';
        else
        {
            dst = print_A(dst, end);
            dst = print_A(dst, end);
        }
    }
    *dst = '';
    return dst;
}
static char *print_A(char *dst, char *end)
{
    assert(dst <= end);
    if (dst < end)
    {
        if (zero_or_one() == 1)
            *dst++ = '1';
        else
        {
            dst = print_S(dst, end);
            dst = print_S(dst, end);
        }
    }
    *dst = '';
    return dst;
}
int main(void)
{
    srand(time(0));
    for (int i = 0; i < 25; i++)
    {
        char buffer[100];
        (void)print_A(buffer, buffer + sizeof(buffer) - 1);
        printf("%sn", buffer);
        (void)print_S(buffer, buffer + sizeof(buffer) - 1);
        printf("%sn", buffer);
    }
    return 0;
}

请注意,序列通常很短,但也可能很长。运行示例:

01011
0
1
0
1
0
00
11
1
0
1
0
1
1110
00
101110101000000011100001110000100111011011000110001000000111010001000110000100010000111111001100011
1
0
11000011111000110011001000011100
0
1
1000000100001000
011
0
110
0
1
0
1
001
1
0110110011000
11110011110101100101100000111101011010001000110110010100011001100
10111001100101
1
100
100010
0
00
0
011
11
0000100010110
0
1
11
00
0
1
0

一些示例运行被截断为99个字符,就像本例中的长运行一样。我也试过300号和1000号;在这两种情况下,我都得到了被截断的样本运行。

如果你想进行动态内存分配,你必须更狡猾一点:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/* One of these is sufficient; symmetry requires both */
static char *print_S(char **buffer, size_t *len, char *dst);
static char *print_A(char **buffer, size_t *len, char *dst);
static int zero_or_one(void)
{
    int rv = rand() % 2;
    return rv;
}
static void add_space(char **buffer, size_t *len, char **dst)
{
    assert(*dst < *buffer + *len);
    if (*dst == *buffer + *len - 1)
    {
        char *newbuf = realloc(*buffer, 2 * *len);
        if (newbuf == 0)
        {
            fprintf(stderr, "Out of memory (%zu)n", 2 * *len);
            exit(1);
        }
        *len *= 2;
        *buffer = newbuf;
        *dst = *buffer + strlen(*buffer);
    }
}
static char *print_S(char **buffer, size_t *len, char *dst)
{
    add_space(buffer, len, &dst);
    if (zero_or_one() == 0)
        *dst++ = '0';
    else
    {
        dst = print_A(buffer, len, dst);
        dst = print_A(buffer, len, dst);
    }
    *dst = '';
    return dst;
}
static char *print_A(char **buffer, size_t *len, char *dst)
{
    add_space(buffer, len, &dst);
    if (zero_or_one() == 1)
        *dst++ = '1';
    else
    {
        dst = print_S(buffer, len, dst);
        dst = print_S(buffer, len, dst);
    }
    *dst = '';
    return dst;
}
int main(void)
{
    srand(time(0));
    size_t len = 100;
    char *buffer = malloc(len);
    for (int i = 0; i < 25; i++)
    {
        (void)print_A(&buffer, &len, buffer);
        printf("%zu: %sn", strlen(buffer), buffer);
        (void)print_S(&buffer, &len, buffer);
        printf("%zu: %sn", strlen(buffer), buffer);
    }
    free(buffer);
    return 0;
}

这样,我得到了一次运行,其中输出字符串为14473874字节长。我不想在这里打印它;足以说明其中有1和0。

相关内容

  • 没有找到相关文章

最新更新