указатель массива инициализирован, но не может присвоить ему какие-либо значения? программа на с - PullRequest
1 голос
/ 15 февраля 2011
#define LINE_LEN        80
#define MAX_ARGS        64
#define MAX_ARG_LEN     64
#define MAX_PATHS       64
#define MAX_PATH_LEN    96

#ifndef NULL
#define NULL            0
#endif

...

struct command_t {
    char *name;
    int argc;
    char *argv[MAX_ARGS];
};

...

/* Command initialisation, allocate type command */
    struct command_t command;
    command.name = (char *) malloc(LINE_LEN);
    command.argc = 0;
    for(ii=0; ii < MAX_ARGS; ii++) {  /* i < 64 */
        command.argv[ii] = (char *) malloc(MAX_ARG_LEN); 
    }

... передать некоторые значения в command.argv, у меня есть что-то вроде command.argv [0] = "man" и command.argv [1] = "сокет", command.argc = 2, command.name = "name", например, вот так

command.name = "man"
command.argc = 2
command.argv[0] = "man"
command.argv[1] = "socket"
command.argv[2] = ""
command.argv[3] = ""
...
command.argv[63] = ""

, тогда возникает вопрос, когдаЯ сделал ниже:

        char *argTemp[command.argc+1];
        for(ii = 0; ii < command.argc+1; ii++){
            if(strlen(command.argv[ii])){
                argTemp[ii] = (char *)malloc(strlen(command.argv[ii])+1); /*added +1*/
                /*   argTemp[ii] = command.argv[ii];  */ 
                /*delete the line above, problem still exist*/
                strcpy(argTemp[ii], command.argv[ii]);
            } else {
                argTemp[ii] = (char*)NULL;
            }
        }

Распределение памяти для команды прошло успешно, все работает для команды.однако, используя ту же технику для argTemp [], в отладчике я вижу, что argTemp равен [0], в нем ничего нет и он ни на что не указывает.Я не понимаю почему?Я ожидаю увидеть artTemp [] таким же, как command.argv [], только избавиться от лишней нулевой памяти.как это:

argTemp[0] = "man"
argTemp[1] = "socket"
argTemp[3] = "\000"

, то есть больше не argTemp, тогда я освобожу command.argv и указываю command.argv на argTemp.Таким образом, вы, вероятно, видите, что все, что я пытаюсь сделать здесь, это избавиться от памяти с нулевым значением в command.argv.

Ответы [ 2 ]

1 голос
/ 15 февраля 2011

Я запустил следующую программу:

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

#define LINE_LEN        80
#define MAX_ARGS        64
#define MAX_ARG_LEN     64
#define MAX_PATHS       64
#define MAX_PATH_LEN    96

#ifndef NULL
#define NULL            0
#endif

struct command_t {
    char *name;
    int argc;
    char *argv[MAX_ARGS];
};

int main() {
    size_t ii;  // Assumed

    /* Command initialisation, allocate type command */
    struct command_t command;
    command.name = (char *) malloc(LINE_LEN);
    command.argc = 0;
    for(ii=0; ii < MAX_ARGS; ii++) {  /* i < 64 */
        command.argv[ii] = (char *) malloc(MAX_ARG_LEN);
    }

    command.name = "man";
    command.argc = 2;
    command.argv[0] = "man";
    command.argv[1] = "socket";

    size_t argc = command.argc; // Assumed

    char *argTemp[argc+1];
    for(ii = 0; ii < argc+1; ii++){
        if(strlen(command.argv[ii])){
            argTemp[ii] = (char *)malloc(strlen(command.argv[ii]));
            strcpy(argTemp[ii], command.argv[ii]);
        } else {
            argTemp[ii] = (char*)NULL;
        }
    }

    printf("argTemp[0] == %p (%s)\n", argTemp[0], argTemp[0]);

    return 0;
}

Я получаю следующий вывод:

argTemp[0] == 0x159bd470 (man)

Исходя из того, что вы написали, это то, что я ожидаю, но это не такчто ты получаешьВаша проблема, кажется, в другом месте.Можете ли вы опубликовать полный пример кода, повторяющий проблему?

Я заметил несколько ошибок и проблем в вашем коде:

  1. Вы переходите к argTemp[3], что, вероятно,не то, что вы хотите.Удалите +1 из последнего цикла for.
  2. Вы не инициализируете command.argv[ii] пустой строкой.Простое написание command.argv[ii][0] = '\0'; исправит это.
  3. Вы дважды звоните strlen.Вместо этого вы должны кэшировать результат strlen.
  4. Вы выделяете память для своих командных строк, но в итоге вы просто переназначаете командные строки.Это может быть для примера, но если вы перенастраиваете , у вас есть утечка памяти (так как вы не free не редактируете malloc память).
  5. Вы только выделяете достаточно памяти для содержимого строки, а не нулевой терминатор в конце строки.strcpy, таким образом, напишет '\0' в argTemp[ii][strlen(command.argv[ii])], что является неопределенным поведением.
1 голос
/ 15 февраля 2011

= не копирует строку в C, он только копирует указатель.Из вашего описания звучит так, как будто вы, вероятно, теряете кучу памяти из упомянутых вами строк

command.argv[0] = "man";

.Наиболее заметная проблема связана с этим назначением во втором кодовом блоке:

argTemp[ii] = command.argv[ii];

Это назначение пропускает выделение, которое вы только что сделали в предыдущей строке (в которой, кстати, вероятно, должно быть +1),В строке после вы пытаетесь сделать strcpy(), но после этого присваивания вы просто делаете strcpy() из одной строки в одну и ту же строку и фактически не копируете какие-либо значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...