gpt4 book ai didi

c - 为什么此代码在编写异常时会引发访问冲突?

转载 作者:行者123 更新时间:2023-11-30 19:17:06 27 4
gpt4 key购买 nike

有谁知道为什么以下代码会引发访问冲突写入异常?

void squeeze_c(char s[], int c)
{
int i, j;

for (i = j = 0; s[i] != '\0'; i++)
{
if (s[i] != c)
s[j++] = s[i];
s[j] = '\0';
}
}

我调用该函数如下:

squeeze_c("Test", 's');

最佳答案

该代码本质上没有任何问题,因此可以归结为两种可能性(可能更多,但根据我的经验,这些是最常见的)。

  1. 您正在传递一个非字符串,即不以 \0 字符结尾的内容。

  2. 您正在传递一个字符串文字,这是您不允许修改的内容。

Now that you've specifically stated you're calling it with squeeze_c("Test", 's');, point two above is the correct one.

<小时/>

前者是如果您执行以下操作:

char str[] = {'n','o',' ','n','u','l',' ','h','e','r','e'};

您可以通过简单地确定它的末尾一个\0来解决这个问题。

<小时/>

后者是如果您执行以下操作之一:

squeeze_c("this is a literal", 'l');

或者:

char *xyzzy = "another literal";
squeeze_c(xyzzy, 'l');

您可以通过确保拥有文字的可写副本来解决这个问题,例如:

char xyzzy[] = "another literal";
squeeze_c(xyzzy, 'l');
<小时/>

而且您确实不想在内循环中添加\0,因为它可能会损坏您的源字符串。

考虑是否使用:

char xyzzy[] = "paxdiablo";
squeeze_c (xyzzy, 'd');

第一次循环时,您将用自身覆盖 p ,然后用 \0 覆盖 a . 然后您将退出循环,因为在索引 i 处找到的下一个字符将是您刚刚写入字符串的 \0)。

因此,它不会删除所有 d 字符,而是将整个字符串截断为长度。

相反,你最好这样做:

void squeeze_c(char *s, int c) {
int i, j;
for (i = j = 0; s[i] != '\0'; i++)
if (s[i] != c)
s[j++] = s[i];
s[j] = '\0'; // moved outside the loop
}

这将按如下方式转换字符串(其中 | 代表 \0):

paxdiablo|     original string
paxdiablo| copy p over p
paxdiablo| copy a over a
paxdiablo| copy x over x
paxdiablo| no copy, j now one less than i
paxiiablo| copy i over d
paxiaablo| copy a over i
paxiabblo| copy b over a
paxiabllo| copy l over b
paxiabloo| copy o over l
paxiablo|| final placement of \0

关于c - 为什么此代码在编写异常时会引发访问冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28654503/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com