Программа на C Изменение argv программно выдает ошибку повреждения кучи после выхода из программы только в режиме отладки в Visual Studio. Как решить?

В настоящее время нет способа выбрать родительский элемент элемента в CSS.

Если бы был способ сделать это, это было бы в любой из текущих спецификаций селекторов CSS:

Тем временем, вам придется прибегнуть к JavaScript, если вам нужно выбрать родительский элемент.


Рабочий блок для выбора уровня 4 включает псевдокласс класса :has(), который работает аналогично реализации jQuery . По состоянию на 2018 год это все равно не поддерживается никаким браузером .

Используя :has(), исходный вопрос можно было бы решить с помощью этого:

li:has(> a.active) { /* styles to apply to the li tag */ }

-1
задан Ganesh Kamath - 'Code Frenzy' 28 March 2019 в 04:48
поделиться

4 ответа

Вы не можете возиться с argv, как это. argv не ваше, оно было выделено и заполнено при запуске программы в соответствии с командной строкой.

Если вы вызываете свою программу следующим образом:

program a b c

, тогда argc равно 4, argv[0] указывает на "program", argv[1] указывает на "a" и т. Д.

argv[argc] - это NULL

Но доступ к argv[5] и далее является неопределенным поведением, потому что вы получаете доступ к массиву вне границ.

Эта статья SO тоже может помочь: Насколько опасен доступ к массиву за пределами? .

Чтобы решить вашу проблему: не обращайтесь к массивам за пределами.

0
ответ дан Jabberwocky 28 March 2019 в 04:48
поделиться

Для решения этой проблемы я создал отдельную переменную char ** и использовал эту переменную в коде для решения проблемы.

Вот как выглядел новый код:

#include <stdio.h>
int main(int argc, char **argv)
{
    int nargc = 12;
    char **nargv;
    nargv = malloc(sizeof(char*)*nargc);

    nargv[0] = malloc(1 + strlen(argv[0]));
    strcpy(nargv[0], argv[0]);

    nargv[1] = malloc(1 + strlen("srt1"));
    strcpy(nargv[1], "srt1");

    nargv[2] = malloc(1 + strlen("srt2"));
    strcpy(nargv[2], "srt2");

    nargv[3] = malloc(1 + strlen("srt3"));
    strcpy(nargv[3], "srt3");

    nargv[4] = malloc(1 + strlen("srt4"));
    strcpy(nargv[4], "srt4");

    nargv[5] = malloc(1 + strlen("srt5"));
    strcpy(nargv[5], "srt5");

    nargv[6] = malloc(1 + strlen("srt6"));
    strcpy(nargv[6], "srt6");

    nargv[7] = malloc(1 + strlen("srt7"));
    strcpy(nargv[7], "srt7");

    nargv[8] = malloc(1 + strlen("srt8"));
    strcpy(nargv[8], "srt8");

    nargv[9] = malloc(1 + strlen("srt9"));
    strcpy(nargv[9], "srt9");

    nargv[10] = malloc(1 + strlen("srt10"));
    strcpy(nargv[10], "srt10");

    nargv[11] = malloc(1 + strlen("srt11"));
    strcpy(nargv[11], "srt11");

    /* Useful code */

    free(nargv[11]);
    free(nargv[10]);
    free(nargv[9]);
    free(nargv[8]);
    free(nargv[7]);
    free(nargv[6]);
    free(nargv[5]);
    free(nargv[4]);
    free(nargv[3]);
    free(nargv[2]);
    free(nargv[1]);
    free(nargv[0]);


    free(nargv);
    printf("Hello world\n");
    return 0;
}
0
ответ дан Ganesh Kamath - 'Code Frenzy' 28 March 2019 в 04:48
поделиться

Вам разрешено изменять argc и argv, но это не значит, что C внезапно обрабатывает (пере) распределение этих переменных для вас. argv будет массивом типа char* argv[argc];. Он будет содержать столько указателей, сколько argc говорит, что он содержит, не больше, не меньше. Точно так же длина каждой строки, на которую указывает argv[i], равна длине, которую передал вызывающий.

Пример:

myprog.exe foo 
  • Это означает, что argc == 2 и argv будут иметь длину 2. Это не может быть изменено вашей программой.
  • argv[0] будут указывать на модифицируемую строку "myprog.exe", размер 10 + 1 = 11 байтов. Вы можете изменить содержимое, но не хранить в нем ничего длиннее 11 байт.
  • argv[1] будет указывать на строку "foo", размер 3 + 1 = 4 байта. Вы можете изменить содержимое, но не хранить там ничего длиннее 4 байт.

(Любопытство: это совершенно нормально и, пожалуй, самый правильный способ определить argv как VLA следующим образом:
int main (int argc, char* argv[argc]), потому что argv распадается на char** в любом случае.)


То, что все сказанное, изменение argc и argv, хотя и допускается стандартом C, является ужасно плохой практикой. Не делай этого. Вместо этого вы должны использовать локальную переменную и позволить ей ссылаться на argv, где это необходимо. Пример:

int main (int argc, char* argv[])
{
  const char* argstr [12] = 
  {
    "str0",
    "str1",
    "str2",
    "str3",
    "str4",
    "str5",
    "str6",
    "str7",
    "str8",
    "str9",
    "str10",
    "str11",
  };

  for(int i=0; i<argc; i++)
  {
    argstr[i] = argv[i];
  }

  /* always use argstr here, never argv */

  return 0;
}
0
ответ дан Lundin 28 March 2019 в 04:48
поделиться

Допустимо изменить символы строк аргумента . C11 5.1.2.2.1p2

Параметры argc и argv и строки, на которые указывает массив argv, должны изменяться программой и сохранять их последние сохраненные значения между запуском программы и завершением программы.

До сих пор не разрешен доступ к массиву за пределами, argv будет иметь только только argc + 1 элементов, не так много, как вы пытаетесь туда вставить. .

0
ответ дан Antti Haapala 28 March 2019 в 04:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: