0

タイトルが示すように、(独自の文字列型とライブラリを使用して) 文字列をコピーしようとすると、セグメンテーション エラーが発生します。デバッガーによると、ソースの 29 行目 (s_strcpy4() が呼び出される場所) で発生し、sstring.h の "_dest[i] = _sour[i];" の行に移動します。クラッシュ時に時々異なる値を持っているようですが、1つの値に固執する場合があります(理由はまだわかりません)。執筆時点では、16896 で止まっています。

コードでセグメンテーション違反を引き起こしている可能性がある場所を知っている人はいますか?

source.c

#include "sstring.h"
#include <string.h>
#include <stdio.h>
#include <time.h>

int main(void) {
    s_string ss1,
                     ss2;
    long long int start, end;
    struct timespec time;
    FILE *LoremIpsum;

    s_init(&ss1, NULL, 65536);
    s_init(&ss2, NULL, 65536);

    LoremIpsum = fopen("Lorem ipsum", "r");
    if(LoremIpsum == NULL) {
        perror("Error opening file ");
        return 1;
    }

    fgets(ss2.string, 65536, LoremIpsum);

    if(fclose(LoremIpsum) == EOF) {
        perror("Error closing file ");
        return 2;
    }

    s_strcpy4(&ss1, &ss2);

    return 0;
}

sstring.h

#include <stdlib.h>
#include <stdint.h>

    enter code here

typedef struct {
    int length;
    char *string;
} s_string;

s_string *s_init(s_string *str, char *array, size_t num) {
    int i;

    if(str == NULL) 
        str = malloc(sizeof(s_string));

    if(array == NULL) {
        (*str).length = num;

        if(num != 0)
            (*str).string = malloc(num);
    } else {
        if(num == 0) {
            (*str).string = NULL;

            for(i = 0; array[i] != '\0'; i++) {
                (*str).string = realloc((void *)(*str).string, i + 1);
                (*str).string[i] = array[i];
            }

            (*str).length = i;
        } else {
            (*str).string = (char *)malloc(num);

            (*str).length = num;

            for(i = 0; i < num; i++)
                (*str).string[i] = array[i];
        }
    }

    return str;
}

s_string *s_strcpy4(s_string *__restrict__ destination, const s_string *__restrict__ source) {
    int i;
    long long  *_dest = (long long *)(destination->string),
                         *_sour = (long long *)(source->string);

    for(i = 0; i < source->length - 8; i+=8)
        _dest[i] = _sour[i];

    for( ; i < source->length; i++)
        destination->string[i] = source->string[i];

    destination->length = i;

    return destination;
}
4

2 に答える 2

1

_dest[i] = _sour[i]; _dest[i/8] = _sour[i/8]; である必要があります。

または同等のもの。

コードには他にも多くの問題があります。たとえば、適切にアラインされたポインタを必要とするアーキテクチャでは、8 の倍数のアドレスで始まらない 8 文字のグループにアクセスしようとすると、バス エラーが発生します。

これは演習として行っており、本番環境では使用していないと思います。memcpy() を使用するだけです

于 2013-07-29T02:37:46.917 に答える
0
size_t const LLsize = sizeof(long long);
for(i = 0; i < source->length / LLsize; ++i)
    _dest[i] = _sour[i];

for( i = i*LLsize; i < source->length; ++i)
    destination->string[i] = source->string[i];
于 2013-07-29T09:04:11.037 に答える