提问人:OldCrow 提问时间:7/1/2023 最后编辑:OldCrow 更新时间:7/1/2023 访问量:69
C语言中的“写入访问冲突”是什么意思,我该如何解决这个问题?
What means "write access violation" in C and how do I solve this?
问:
所以我对 C 语言完全陌生。我有 Visual Basic 和 C# 的背景,在这些语言中,我通常不需要关心低级的东西。最近开始学习指针,我正在做一些 leetcode 挑战来练习。
**这里是挑战文字:** 编写一个函数以查找字符串数组中最长的公共前缀字符串。 如果没有通用前缀,则返回空字符串 “”。
这是我的尝试:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
char* longestCommonPrefix(char** strs, int strsSize) {
if (strsSize == 1) return strs[0];
if (strs[0] == "") return "";
char* result = strs[0];
size_t result_length = strlen(result) - 1;
char* result_end = strs[0] + result_length;
for (size_t i = 1; i < strsSize; ++i) {
size_t length = strlen(strs[i]) - 1;
if (length < 1) return "";
if (length < result_length) {
result_end = strs[0] + length;
result_length = length;
}
char* temp1 = result;
char* temp2 = strs[i];
while (*temp1 == *temp2 && temp1 < result_end) {
++temp1;
++temp2;
}
if (temp1 < result_end) {
result_end = temp1 - 1;
result_length -= strlen(result_end) - 1;
}
}
*(result_end + 1) = '\0';
return result;
}
int main(int argc, char* argv[]) {
char* a[3];
a[0] = "flower";
a[1] = "flight";
a[2] = "flow";
char* b = longestCommonPrefix(a, 3);
printf(b);
}
为什么我在线路上收到写入访问冲突错误?
在谷歌上搜索这个,我发现文章说 c 字符串是只读的,为什么呢,有什么解决方法?
此外,任何通用的 C 提示或指向此类内容的链接也值得赞赏,谢谢。*(result_end + 1) = '\0';
编辑:感谢@Chris的解决方案。 这是我的新代码,它工作得很好。还要感谢 @@WeatherVane 的一般 C 技巧,我还将他的知识包含在我的新代码中。
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
char* longestCommonPrefix(char** strs, int strsSize) {
if (strsSize == 1) return strs[0];
if (strs[0][0] == 0) return "";
char* result = _strdup(strs[0]);
size_t result_length = strlen(result) - 1;
char* result_end = strs[0] + result_length;
for (size_t i = 1; i < strsSize; ++i) {
char* str = _strdup(strs[i]);
size_t length = strlen(str) - 1;
if (length < 1) return "";
if (length < result_length) {
result_end = str + length;
result_length = length;
}
char* temp = result;
while (*temp == *str && temp < result_end) {
++temp;
++str;
}
if (temp < result_end) {
result_end = temp - 1;
result_length -= strlen(result_end) - 1;
}
}
*(result_end + 1) = '\0';
return result;
}
int main(int argc, char* argv[]) {
char* a[3];
a[0] = "flower";
a[1] = "flight";
a[2] = "flow";
char* b = longestCommonPrefix(a, 3);
printf(b);
}
答:
0赞
Chris
7/1/2023
#1
这意味着你已经写入了一些你不应该写入的内存。
你有一个指针数组。但每个都指向一个字符串文字,即 .main
char
const char *
然后,尝试修改这些字符串文本,这将调用未定义的行为。longestCommonPrefix
如果您希望在函数中修改这些值,则应将这些字符串文字复制到分配的内存中。strdup
是一种非常简单的方法,只要您确保事后释放动态分配的内存即可。longestCommonPrefix
char *a[3];
a[0] = strdup("flower");
a[1] = strdup("flight");
a[2] = strdup("flow");
如果你的工具不允许使用此函数,你可以声明保存 3 个固定长度的字符串,或者手动处理动态内存分配和复制。a
评论
1赞
Eric Postpischil
7/1/2023
由于遗留原因,C 语言中字符串文字的类型是 的数组 ,而不是 ,并且在适当的情况下,它会自动转换为 、 not 。不应该教学生期望,因为他们不能依赖编译器通过类型限定符捕获错误。C 标准不定义程序尝试修改字符串文本时的行为。这意味着在可移植代码中可以避免使用它,但这也意味着 C 实现可以支持修改字符串文字,如果其实现者需要。char
const char
char *
const char *
const char *
1赞
Chris
7/1/2023
使用 UB 代码可能做的最危险的事情:按预期工作。
1赞
Jonathan Leffler
7/1/2023
请注意,这在 C23 中成为标准 C 的一部分(也是如此)。strdup()
strndup()
0赞
OldCrow
7/1/2023
感谢大家提供的信息。@Chris您的解决方案工作正常,但是对于leetcode挑战,我无法访问main,因此我只是将其添加到函数中。此外,我收到一个警告 strdup 已弃用,我应该使用_strdup因为它是 ISO 标准。无论如何,非常感谢你。为了清楚起见,我将把我的新代码添加到问题中。
评论
fl
if (strs[0] == "")
strcmp()
if (strs[0][0] == 0)