Причина Почему это происходит в c [duplicate]

Другое решение состоит в том, чтобы выполнить код через последовательный исполнитель nsynjs .

Если базовая функция многозначна

nsynjs будет последовательно оценивать все обещания и ставить обещания результат в свойство data:

function synchronousCode() {

    var getURL = function(url) {
        return window.fetch(url).data.text().data;
    };
    
    var url = 'https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js';
    console.log('received bytes:',getURL(url).length);
    
};

nsynjs.run(synchronousCode,{},function(){
    console.log('synchronousCode done');
});

Если базовая функция не обещает

Шаг 1. Wrap с обратным вызовом в оболочку, совместимую с nsynjs (если у нее есть обещанная версия, вы можете пропустить этот тест):

var ajaxGet = function (ctx,url) {
    var res = {};
    var ex;
    $.ajax(url)
    .done(function (data) {
        res.data = data;
    })
    .fail(function(e) {
        ex = e;
    })
    .always(function() {
        ctx.resume(ex);
    });
    return res;
};
ajaxGet.nsynjsHasCallback = true;

Шаг 2. Вставить синхронную логику в функцию:

function process() {
    console.log('got data:', ajaxGet(nsynjsCtx, "data/file1.json").data);
}

Шаг 3. Выполнить функцию синхронно через nnsynjs:

nsynjs.run(process,this,function () {
    console.log("synchronous function finished");
});

Nsynjs будет оценивать все операторы и выражения шаг за шагом, приостанавливая выполнение в случае, если результат некоторой медленной функции не готов.

Дополнительные примеры здесь: https://github.com/amaksr/nsynjs/tree/master/examples

11
задан alk 17 January 2015 в 09:53
поделиться

7 ответов

  1. C не проверяет границы массива. Ошибка сегментации будет возникать только в том случае, если вы попытаетесь разыменовать указатель на память, в котором у вашей программы нет разрешения на доступ. Просто пройти мимо конца массива вряд ли вызовет такое поведение. Неопределенное поведение - это просто неопределенное. Это может показаться , что работает нормально, но вы не должны полагаться на его безопасность.
  2. Ваша программа вызывает неопределенное поведение, обращаясь к памяти за конец массива. В этом случае одна из ваших записей str[i] = c перезаписывает значение в i.
  3. C ++ имеет те же правила, что и в C.
20
ответ дан Carl Norum 26 August 2018 в 10:06
поделиться

Поскольку C / C ++ не проверяет границы.

Массивы внутренне указывают на местоположение в памяти. Когда вы вызываете arr[index], что он делает, это:

type value = *(arr + index);

Результаты - это большие числа (не обязательно), потому что они являются значениями мусора. Также как неинициализированная переменная.

2
ответ дан Aidiakapi 26 August 2018 в 10:06
поделиться

Распределение памяти сложнее, чем кажется. Переменная «str» в этом случае находится в стеке, рядом с другими переменными, поэтому за ней не следует нераспределенная память. Память также обычно выравнивается по слову (одно «слово» - от четырех до восьми байтов.) Возможно, вы сошлись со значением для другой переменной или с некоторым «дополнением» (пустое пространство, добавленное для поддержания выравнивания слов), или что-то еще полностью .

Как сказал Р., это неопределенное поведение. Условия вне границ могут вызвать segfault ... или они могут привести к повреждению памяти. Если вы изменяете уже выделенную память, это не будет зависеть от операционной системы. Вот почему ошибки вне границ настолько коварны в C.

0
ответ дан Max E. 26 August 2018 в 10:06
поделиться

Вы должны скомпилировать так:

gcc -fsanitize=address -ggdb -o test test.c

Здесь есть дополнительная информация.

0
ответ дан Nathaniel Ford 26 August 2018 в 10:06
поделиться

Написание внешних границ массива (фактически даже просто выполнение арифметики указателя / массива, даже если вы не используете результат для чтения или записи чего-либо) приводит к неопределенному поведению. Неопределенное поведение не является сообщенной или отчетливой ошибкой; это мешает вашей программе вообще что-либо сделать. Это очень опасно, и вы несете полную ответственность за его устранение. C не является Java / Python / и т. Д.

0
ответ дан R.. 26 August 2018 в 10:06
поделиться

C не проверяет границы массива.

На самом деле ошибка сегментации не является специфической ошибкой во время выполнения, порожденной превышением границ массива. Скорее, это результат защиты памяти, предоставляемой операционной системой. Это происходит, когда ваш процесс пытается получить доступ к памяти, которая ему не принадлежит, или пытается получить доступ к адресу памяти, который не существует.

2
ответ дан Tom 26 August 2018 в 10:06
поделиться

Когда вы обращаетесь к индексу массива, C и C ++ не выполняют проверку привязки. Ошибки сегментации возникают только при попытке чтения или записи на страницу, которая не была выделена (или попытаться сделать что-то на странице, которая не разрешена, например, попытка записи на страницу только для чтения), но поскольку страницы обычно довольно большой (кратные несколько килобайт, в Mac OS, кратные 4 КБ), он часто оставляет вам много места для переполнения.

Если ваш массив находится в стеке (например, ваш), он может быть еще хуже, поскольку стек обычно довольно большой (до нескольких мегабайт). Это также является причиной проблем безопасности: запись за пределы массива в стеке может перезаписать обратный адрес функции и привести к произвольному выполнению кода (известные нарушения безопасности переполнения буфера).

Значения, которые вы получаете при чтении, - это то, что происходит в этом конкретном месте. Они полностью не определены.

Если вы используете C ++ (и вам повезло работать с C ++ 11), стандарт определяет тип std::array<T, N>, который является массивом, который знает свои границы. Метод at будет бросаться, если вы попытаетесь прочитать его конец.

6
ответ дан zneak 26 August 2018 в 10:06
поделиться
Другие вопросы по тегам:

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