Как я могу изменить адрес памяти char *?

#c #arrays #char

#c #массивы #char

Вопрос:

Я имею дело с проблемой, заключающейся в том, что я не могу получить abs_path и массивы запросов, заполненные данными, которые я передаю им внутри синтаксического анализа функции. Внутри этой функции логика кажется правильной, я ее отладил, и оба массива заполнены правильными данными. Я знаю, что я не передаю указатель на массивы (char **) в параметрах из-за условия, что параметры функции не могут быть изменены. Любые другие советы по решению этой проблемы?

 #define LimitRequestLine 8190
char abs_path[LimitRequestLine   1];
char query[LimitRequestLine   1];

bool parse(const char* line, char* abs_path, char* query)
{
    char* method = "GET ";
    char* valid_http = "HTTP/1.1";
    int index, method_size;
    char abs_path_line[LimitRequestLine   1];
    char query_line[LimitRequestLine   1];
    int abs_path_index;

    if(strstr(line, "HTTP/")!=NULL amp;amp; strstr(line, valid_http) == NULL) {
        error(505);
        return false;
    }

    //make sure that our method is GET
    for(index = 0, method_size = strlen(method); index<method_size; index  ) {
        if(line[index] != method[index]) {
            error(405);
            return false; 
        }
    }

    //check if request-target starts with '/'
    if(line[index]!='/') {
            error(501);
            return false; 
    }

    for(abs_path_index = 0; index < strlen(line); index  ) {

       //if there is a quotation mark, then we have a query in request-target
       if(line[index] == '?') {
        index  ;
        int query_index;

        for(query_index = 0; line[index]!=' '; index  ) {

            //check if there is quote mark in query
            if(line[index] == '"') {
                error(400);
                return false; 
            }

            query_line[query_index] = line[index];
            query_index  ;
        }

            query_line[query_index] = '';
       }

       //assuming that we have not found any '?' mark for query.
       if(strstr(line, "?") == NULL) {
          query_line[0] = ''; 
       }

       if(line[index] == ' ') {

           int temp = index;
           index  ;

           /*After the space there should be a valid http, if it is not found,
           then there is/are spaces in our request-line which is incorrect*/
           for(int i=0; i<strlen(valid_http); i  ) {
               if(line[index] != valid_http[i]) {
                   error(400);
                   return false; 
               }
               index  ;
           }

           index = temp;
           break;
       }

       //check if there is quote mark in abs_path
        if(line[index] == '"') {
            error(400);
            return false; 
        }

        abs_path_line[abs_path_index]  = line[index];
        abs_path_index  ;
    }

    abs_path_line[abs_path_index]  = '';

    abs_path = abs_path_line;
    abs_path  = '';
    query = query_line;
    printf("abs path is %sn", abs_path);
    printf("query is %sn", query);


    return true;
}
 

Ответ №1:

Проблема заключается в следующем:

 query = query_line;
 

char *query означает, что вам передан указатель. Это просто число, как и любое другое число. Подумайте об этом так.

 void set_number(int number) {
    number = 6;
}
 

Вы ожидаете, что это что-нибудь сделает? Нет. То же самое с query = query_line .

Вместо query этого указывает на кусок памяти. Вам нужно скопировать query_line в память, на которую query указывает, и надеяться, что там достаточно выделенного места.

 strncpy(query, query_line, LimitRequestLine);
 

Функции, которые требуют, чтобы вызывающий выделял память, — это проблемы с памятью, ожидающие своего появления. Вместо исправления этого я бы рекомендовал…

  1. Написание новой функции с лучшей сигнатурой, возможно, возвращающей структуру.
  2. Реализуйте эту старую функцию как оболочку вокруг новой.
  3. Отказ от этой функции.

Обратите внимание, что query в вашей функции не совпадает с query объявленным вне функции.

Комментарии:

1. Спасибо за ваш отличный ответ! Это именно то, что я искал 🙂