访问冲突读取位置和错误读取字符串的字符

Posted

技术标签:

【中文标题】访问冲突读取位置和错误读取字符串的字符【英文标题】:Access violation reading location and error reading character of string 【发布时间】:2017-12-15 13:35:10 【问题描述】:

谁能解释为什么会抛出访问冲突读取位置错误以及为什么在 a[] 中我得到“错误读取字符串的字符”?我有两个字符串,必须从包含其他字符串的第一个字符串中删除所有单词。我做错了什么?

#include "stdafx.h"
#include<iostream>
#include<cstring>
using namespace std;
char s1[100] = ;
char s2[100] = ;
void Words(char s1[], char s2[]) 
  int k = 0;
  char*p1 = nullptr;
  char*np1 = nullptr;
  char*p2 = nullptr;
  char*np2 = nullptr;
  char *m[20];
  char *a[20];
  char s3[100] = ;
  for (int i = 0; i < 20; i++) 
    char n[50] = ;
    char l[50] = ;
    m[i] = n;
    a[i] = l;

  
  char delimeter[] = " ,.!?;:";
  p2 = strtok_s(s2, delimeter, &np2);
  while (p2 != nullptr) 
    strcpy(a[k], p2);
    k++;
    p2 = strtok_s(nullptr, delimeter, &np2);
  
  k = 0;
  p1 = strtok_s(s1, delimeter, &np1);
  while (p1 != nullptr) 
    strcpy(m[k], p1);
    k++;
    p1 = strtok_s(nullptr, delimeter, &np1);
  

  for (int i = 0; i < 20; i++) 
    for (int j = 0; j < 20; j++) 
      if (strcmp(m[i], a[j]) != 0 && m[i] != 0 && a[j] != 0) 
        strcat(s3, m[i]);
      
    
  
  puts(s3);
  for (int i = 0; i < 20; i++) 
    delete m[i];
    delete a[i];
  

主要功能:

int main()

  gets_s(s1);
  gets_s(s2);
  Words(s1, s2);
  return 0;

【问题讨论】:

为什么不直接使用std::string?毕竟这是可怕的 c++ 代码,更像是 c。 这是在浪费时间,而且可能弊大于利。你的老师应该感觉不好,你应该用一本好的 C++ 书来补充这门课程。 您选择一个字母的变量名称是不明智的,并且会使您的(已经很奇怪的)代码更难理解。 好的变量名不是为了编译器,也不是为了我们,而是为了,这样你可以在调试时更容易地理解你自己的代码。 BTW Visual Studio 拥有世界一流且非常易于使用的调试器。了解如何使用它。 @ЮраБезлюдний 请指点你的老师here。 【参考方案1】:

这里至少有一个问题:

  for (int i = 0; i < 20; i++) 
    char n[50] = ;
    char l[50] = ;
    m[i] = n;
    a[i] = l;
  

在该循环之后,ma 的所有元素都指向超出范围的变量。一旦离开for 循环的 之间的范围,变量nl 将不复存在。

您对指针有很多误解,您可能应该阅读一些有关 C 语言的好书(您编写的代码实际上是 C 而非 C++)。

肯定有更多错误。

【讨论】:

【参考方案2】:

这里的邪恶太多了,我不知道从哪里开始。

您在静态分配的数组上调用 delete p1p2np1np2 都未分配,您正在写信给他们

请使用string:

const regex re "([^ ,.!?;:]+)" ;
vector<string> s1Tokens sregex_token_iterator(cbegin(s1), cend(s1), re, 1), sregex_token_iterator() ;
vector<string> s2Tokens sregex_token_iterator(cbegin(s2), cend(s2), re, 1), sregex_token_iterator() ;

sort(begin(s1Tokens), end(s1Tokens));
sort(begin(s2Tokens), end(s2Tokens));

set_difference(cbegin(s1Tokens), cend(s1Tokens), cbegin(s2Tokens), cend(s2Tokens), ostream_iterator<string>(cout, "\n"));

Live Example

如果在理解了上面的例子之后你发现自己有兴趣进一步研究的话,这个例子可以很容易地进一步充实,我会从这里开始:https://***.com/a/38595708/2642059

【讨论】:

以上是关于访问冲突读取位置和错误读取字符串的字符的主要内容,如果未能解决你的问题,请参考以下文章

我想使用指针和双指针读取 n 个字符串,我得到一个奇怪的错误,访问违规写入位置 [关闭]

0x5919c8ec (msvcr100d.dll) 处的第一次机会异常:0xC0000005:访问冲突读取位置 0xfeeefeee

访问冲突读取位置 0xcccccccc

访问冲突读取位置0x00000002 [关闭]

奇数访问冲突读取错误/glDrawArrays 使用

选择PixelFormat 访问冲突读取位置