3

我在这里的第一个问题。我使用的是指针数组而不是二维数组。现在,要显示一个元素,我可以使用 *(arr[i]+j),其中 arr 是数组 i 表示行,j 表示列。但是,当我尝试使用相同的符号为任何元素分配值时,代码停止工作。我没有收到编译错误,但是当我运行它时它就会停止工作。有人可以帮助我吗?

这是我的代码

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
    int i,j,k;
    char temp2, temp, *arr[] = {
        "Brinda Roy", 
        "Rakesh Bai", 
        "Neha Saxen", 
        "Ankit Jain"};

    printf("%c",*(arr[3]+8));

    for(i=0;i<4;i++){
        for(j=0, k=9; j<=4, k>=5; j++, k--){
            temp =*(arr[i]+j);
            *(arr[i]+j)=*(arr[i]+k);
            *(arr[i]+k)=temp;
        }

    }

    printf("\nThe array is ");

    for(i=0; i<4; i++){
        printf("\n%s",arr[i]);
    }

    getch();
    return 0;
}
4

4 回答 4

5

运行时崩溃是由于您在arr. 字符串文字"Brinda Roy","Rakesh Bai"和应该被视为"Neha Saxen",因为它们可能存储在程序的只读部分中。尝试更改它们的值会导致未定义的行为,如下面的评论中所述。"Ankit Jain"const char[]

如果要编辑这些只读字符串,则需要将它们复制到非const缓冲区中。


如果你这样做:

char *str = "message"

您不应该修改指向的数据,str因为它指向只读内存。


如果你这样做:

char str[] = "message"

可以修改指向的数据,str因为只读字符串文字"message"正在被复制到数组str中。


您的代码属于上述第一种情况。

于 2012-06-28T23:14:31.153 回答
3

C 允许通过此样式在源中定义的字符串存储在只读数据部分中。检查此输出:

$ cat storage.c
int main(int argc, char* argv[]) {
    char *arr[] = {"hello", "world"};
    arr[1][1]='a';
    return 0;
}
$ make storage
cc     storage.c   -o storage
$ readelf -p.rodata storage

String dump of section '.rodata':
  [     4]  hello
  [     a]  world

我的编译器已将字符串放入.rodata只读数据部分。当我尝试在程序中更新o到 ana时,程序死了:

$ ./storage 
Segmentation fault (core dumped)

这通常适用于将字符串定义如下的任何代码:

char *foo = "string";

如果你想在程序源代码中创建一个可修改的字符串,你可以这样写:

char foo[] = "string";

我不完全确定创建可修改字符串数组的语法是什么;至少以下丑陋的方法有效,但我确信有更好的方法:

char a1[] = "hello";
char a2[] = "world";
char *arr[] = {a1, a2};
于 2012-06-28T23:15:42.227 回答
2

您尝试修改字符串文字。这是禁止的。请注意,即使类型系统("abc"is not const char*)不强制执行此操作,修改字符文字"abc"[1]='c'也会导致未定义的行为。

您必须将数据移动到可写位置。最简单但非标准的方法是使用以下strdup函数:

for(i=0; i<4; i++)
  arr[i]=strdup(arr[i]);

这将为字符串在堆上分配内存并将字符串复制到其中。如果您没有该功能,则必须使用,和strdup来实现它。mallocstrlenmemcpy

请注意,与动态分配的内存一样,您必须释放它;否则,您会遇到内存泄漏。

顺便说一句,访问双指针数组和多维数组的正常方法是arr[i][j].

于 2012-06-28T23:14:31.030 回答
1

您不能以这种方式修改保留的内存:

{"Brinda Roy", 
 "Rakesh Bai", 
 "Neha Saxen", 
 "Ankit Jain"};

当您以这种方式定义 char* 时,它只是读取内存。

于 2012-06-28T23:17:17.233 回答