【问题标题】:C memcpy to swap rows of 2D arrayC memcpy 交换二维数组的行
【发布时间】:2020-10-03 13:12:07
【问题描述】:

我正在尝试使用memcpy C 库函数来交换二维数组(字符串数组)的行。此任务的源文件如下:

ma​​in.c

#include <stdlib.h>
#include "main.h"

char *table[NBLOCK] = {
    "abcdefghi",
    "defghiabc",
    "ghiabcdef",
    "bcaefdhig",
    "efdhigbca",
    "higbcaefd",
    "cabfdeigh",
    "fdeighcab",
    "ighcabfde",
};

int main() {
    swap_rows(table, 0, 2);
    return 0;
}

ma​​in.h

#define NBLOCK 9
#define BLOCK_CELLS 9

void swap_rows(char**, int, int);

shuffle.c

#include <string.h>
#include "main.h"

void swap_rows(char **table, int r1, int r2) {
    char tmp[BLOCK_CELLS];
    size_t size = sizeof(char) * BLOCK_CELLS;

    memcpy(tmp, table[r1], size);
    memcpy(table[r1], table[r2], size); /* SIGSEGV here */
    memcpy(table[r2], tmp, size);
}

swap_rows 函数内部发生分段错误。在上面显示的三个memcpy 调用中,第一个调用按预期工作。我注释掉了最后两个 memcpy 调用并添加到以下行:

table[0][0] = 'z';

但是,分段错误再次发生。为什么我不允许在 swap_rows 函数中覆盖 table 的值?

【问题讨论】:

    标签: c pointers segmentation-fault


    【解决方案1】:

    您不能修改字符串文字。 如需更多信息,请参阅c - Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?

    您可以修改指针的值以交换行。

    void swap_rows(char **table, int r1, int r2) {
        char* tmp;
    
        tmp = table[r1];
        table[r1] = table[r2];
        table[r2] = tmp;
    }
    

    如果您更喜欢使用memcpy()

    void swap_rows(char **table, int r1, int r2) {
        char* tmp;
        size_t size = sizeof(tmp);
    
        memcpy(&tmp, &table[r1], size);
        memcpy(&table[r1], &table[r2], size);
        memcpy(&table[r2], &tmp, size);
    }
    

    【讨论】:

    • 关于“您不允许修改字符串文字”:正确的措辞是 C 标准没有定义当您尝试修改字符串文字时会发生什么。 C 标准实际上并没有禁止尝试;您可以修改它们,或者至少尝试一下。这种区别在这里并没有太大的区别,但总体上理解 C 标准很重要:C 标准提供了一个开放区域,您可以在其中使用已定义的功能并引入您自己的功能;禁止您离开的不是有围墙的花园。
    • 好的,但是使用memcpy将一个指向char的指针的值复制到另一个指向char的指针有点奇怪。
    【解决方案2】:

    在您的代码中,table不是定义为char 的二维数组,它是指向char 的指针数组,用指向字符串文字的指针初始化,不得修改.

    您会遇到分段错误,因为字符串文字存储在受操作系统保护的只读内存中。

    您应该交换swap_rows 中的指针或将table 定义为真正的二维数组,并使用适当的原型交换行:

    #include <stdlib.h>
    
    //#include "main.h"
    #define NBLOCK 9
    #define BLOCK_CELLS 9
    
    void swap_rows(char table[][BLOCK_CELLS], int, int);
    
    char table[NBLOCK][BLOCK_CELLS] = {
        "abcdefghi",
        "defghiabc",
        "ghiabcdef",
        "bcaefdhig",
        "efdhigbca",
        "higbcaefd",
        "cabfdeigh",
        "fdeighcab",
        "ighcabfde",
    };
    
    int main() {
        swap_rows(table, 0, 2);
        return 0;
    }
    
    void swap_rows(char table[][BLOCK_CELLS], int r1, int r2) {
        char tmp[BLOCK_CELLS];
        size_t size = sizeof(tmp);
    
        memcpy(tmp, table[r1], size);
        memcpy(table[r1], table[r2], size);
        memcpy(table[r2], tmp, size);
    }
    

    【讨论】:

      猜你喜欢
      • 2021-11-18
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 2018-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多