Нарушение прав доступа при использовании strcpy?

StackOverflow https://stackoverflow.com/questions/1274626

  •  16-09-2019
  •  | 
  •  

Вопрос

Я попытался заново изобрести функцию strcpy C, но когда я пытаюсь ее запустить, я получаю эту ошибку:

Unhandled exception at 0x00411506 in brainf%ck.exe: 0xC0000005: Access violation writing location 0x00415760.

Ошибка возникает в *dest = *src; линия.Вот код:

char* strcpy(char* dest, const char* src) {
    char* dest2 = dest;
    while (*src) {
        *dest = *src;
        src++;
        dest++;
    }
    *dest = '\0';
    return dest2;
}

РЕДАКТИРОВАТЬ:Ух ты, это было быстро.Вот код вызова (strcpy определен в mystring.c):

#include "mystring.h"
#include <stdio.h>

int main() {
    char* s = "hello";
    char* t = "abc";
    printf("%s", strcpy(s, t));
    getchar();
    return 0;
}
Это было полезно?

Решение

char* s = "hello";
char* t = "abc";
printf("%s", strcpy(s, t));

Компилятор поместил целевой буфер s в постоянную память, поскольку он является константой.

char s[5];
char* t = "abc";
printf("%s", strcpy(s, t));

Должно исправить эту проблему.При этом в стеке выделяется целевой массив, доступный для записи.

Другие советы

Очевидная потенциальная проблема заключается в том, что вашему выходному буферу недостаточно выделенной памяти или вы передали NULL для dest.(вероятно, не для src иначе на линии произошел бы сбой раньше.)

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

Вот пример, который меня устраивает в Windows:

#include <stdlib.h>

char* strcpy(char* dest, const char* src) {
    char* dest2 = dest;
    while (*src) {
        *dest = *src;
        src++;
        dest++;
    }
    *dest = '\0';
    return dest2;
}

void main() {
    char *d = malloc(3);
    strcpy(d, "hello there this is a longish string");
}

Обратите внимание, что в этом случае мне пришлось значительно превысить фактически выделенную память, прежде чем я смог спровоцировать смерть программы - просто «привет» не вылетело, хотя это, безусловно, могло зависеть от различных аспектов компилятора и среды выполнения.

Ваш strcpy() в порядке.Вы пишете в постоянную память.Посмотреть это описание здесь.

Если бы вы написали это, все было бы в порядке:

#include "mystring.h"
#include <stdio.h>

int main() {
    char s[] = "hello";
    char t[] = "abc";
    printf("%s", strcpy(s, t));
    getchar();
    return 0;
}

Существует проблема с вызовом вашей заново изобретенной процедуры strcpy в основной процедуре, как в массиве символов:char* s = "привет";char* t = "abc";попадет в сегмент памяти READ ONLY во время компиляции.Поскольку вы пытаетесь выполнить запись в память, на которую указывает s в подпрограмме strcpy, и поскольку она указывает на место в сегменте ТОЛЬКО ДЛЯ ЧТЕНИЯ, она будет перехвачена, и вы получите исключение.Эти строки доступны ТОЛЬКО ДЛЯ ЧТЕНИЯ!

Прежде чем вызывать эту функцию, убедитесь, что dest выделена память.

Вероятно, проблема с вызывающим абонентом:ты проверил место назначения указатель?Указывает ли это на что-то действительное или просто на мусор?Кроме того, минимум, что вы можете сделать, это проверить наличие нулевых указателей, например, if (!dest || !source) { /* сделать что-нибудь, например вернуть NULL или выдать исключение */ } при входе в функцию.Код выглядит нормально.Не очень безопасно, но ладно.

Есть несколько ошибок.

  1. Вы не выделяете буфер возврата, который может хранить скопированную строку.
  2. Вы не проверяете, имеет ли src значение null перед использованием *src.
  3. Вы оба пытаетесь получить ответ в параметре и вернуть значение.Сделайте то или другое.
  4. Вы можете легко переполнить буфер назначения.

Удачи.

когда код начинает выполнение (обычно он начинается с основной функции).здесь код означает последовательность выполнения. Итак, когда процесс (последовательность выполнения) запускается, создается печатная плата (блок управления процессом), печатная плата имеет полную информацию о процессе, такую ​​как адресное пространство процесса, стек ядра, таблица OFDT, подобная этой .

в твоем коде

char* s = "привет";
char* t = "abc";

это то, что вы взяли на вход из двух строк, подобных этой.

здесь строки (что означает двойные кавычки), которые присутствуют в текстовом разделе адресного пространства процесса.здесь текстовый раздел — это раздел, который присутствует в адресном пространстве процесса, и текстовый раздел, имеющий только разрешения только для чтения.вот почему, когда вы пытаетесь изменить исходную строку/строку назначения, мы НЕ ДОЛЖНЫ разрешать изменять любые данные, присутствующие в текстовом наборе.Итак, именно по этой причине ваш код должен быть ОСТОРОЖНЫМ.надеюсь ты понимаешь.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top