Передача адреса разыменованного указателя в смещение строки - PullRequest
0 голосов
/ 09 марта 2019

Предполагая, что есть такая функция

int foo (char** str, int x)
{
    char* p = *str + x;

    foo2(&p); // declared as int foo2 (char** );
}

(конечно, слишком упрощенно, реальная функция рекурсивна и намного сложнее)


Я пытался сделать это:

int foo (char** str, int x)
{    
    foo2(&(*str + x));
}

Но компилятор завершился ошибкой:

ошибка: lvalue требуется в качестве унарного операнда '&'

Почему компилятор стрелялс этой ошибкой и как передать указатель на указатель на строковые x-байтовые символы без объявления переменной и использования ее собственного адреса?


EDIT

Похоже, есть какое-то недопонимание, поэтому я опубликую полный симулятор того, чего я хочу достичь.

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

char* string = "This is a sample string.";
char* ptr;
int randomizer;

int receive_string (char* buffer, int size) // recv
{
    int i = 0;

    if(ptr == NULL)
        ptr = string;

    for(i = 0; *ptr != '\0' && i < size; ptr++)
    {
        if(randomizer == 2)
        {
            randomizer++;

            break;
        }

        buffer[i] = *ptr;

        i++;

        randomizer++;
    }

    if(*ptr == '\0')
    {
        buffer[i] = *ptr;

        i++;
    }

    return i;
}

int read_string (char* *buffer, int size, int alloc)
{
    int bytes = 0;

    printf("Reading string..\n");

    if(*buffer == NULL && alloc == 1)
    {
        printf("Allocating buffer..\n");

        *buffer = calloc(size, sizeof(char));
    }

    bytes = receive_string(*buffer, size);

    if(bytes == (-1))
    {
        return(-1);
    }
    if(bytes == 0)
    {    
        return 0;
    }
    if(bytes < size)
    {
        char* p = *buffer + bytes;
        //int temp = read_string(&p, size - bytes, 0); // works
        //int temp = read_string(&(char *){&(*buffer)[bytes]}, size - bytes, 0); // works
        int temp = read_string(buffer + bytes, size - bytes, 0); // doesn't work

        if(temp > 0)
            bytes += temp;
        else return bytes;
    }

    return bytes;
}

int main()
{
    char* buffer = NULL;

    int bytes = read_string(&buffer, strlen(string) + 1, 1);

    printf("[%u][%s]\n", bytes, buffer);

    if(buffer)
        free(buffer);

    return 0;
}

randomizer - самый тупой способ "симулировать" recv() который не может получить все байты.Эта реализация моделирует recv(), но вместо чтения из очереди сокетов она читает из глобальной строки.

Ответы [ 3 ]

3 голосов
/ 09 марта 2019

(*str + x) не является lvalue, так как это временное значение, у которого нет адреса, поэтому вы не можете получить его адрес с &.Даже если компилятор сохранил значение во временной переменной в ОЗУ, чтобы его адрес мог быть получен, как бы вы потом ссылались на его значение, если бы foo2 () изменил содержимое временной переменной.

Поэтому вам нужно сохранитьзначение во временной переменной самостоятельно.

0 голосов
/ 09 марта 2019

Я думаю, что следующий код - это то, что вы пытаетесь сделать.Для ударов я сделал это рекурсивным и проверил это с алфавитом для последовательности.Переменные cnt и lmt должны быть глобальными.Он покажет сокращающуюся строку, если вы ее запустите.Просто убедитесь, что p и lmt достаточно малы, чтобы не переполнять строку.

void foo(char *s, int p) {
    cnt++;
    printf("%s\n", s);
    if(cnt != lmt) foo(&s[p], p);
}
0 голосов
/ 09 марта 2019

, если вы хотите передать указатель на указатель на конкретный символ

foo2(&(char *){&(*str)[x]});

или

...