Giter Site home page Giter Site logo

Comments (12)

idealvin avatar idealvin commented on May 4, 2024 2

我在实际使用中改成了先用has_member()判断再访问。
既然有这个问题存在,而文档上并没有禁止这种做法,总感觉应该做点什么来从源头避免这个问题。 😄

可以的,底层分配两块内存可以解决这个问题,但性能会下降一些,武汉疫情稳定些再考虑重构这一块。

可以用 Json 的 find 操作取代 [],效率更高

from coost.

idealvin avatar idealvin commented on May 4, 2024

@tigerlee
json::parse() 传入错误的字符串,v 整个就是null,[]操作key不存在时,自动添加,你那个测试结果是正常的

from coost.

tigerlee avatar tigerlee commented on May 4, 2024

这样允许用户犯错,但犯错的代价有点大啊。我因为这个问题单步调试找了一晚上。:cry:
有没有可能考虑这种方案:定义一个全局的空值,当输入有错时,返回这个空值的引用,不影响原来的Value?这样至少不会影响上面例子中第6行的执行。

from coost.

yanlinlin82 avatar yanlinlin82 commented on May 4, 2024

@tigerlee 我倒是觉得现在的逻辑更合理些,也与STL中map(自动添加)的做法一致。返回全局空值,似乎可能造成更多混乱。真要限制自动添加,或许可考虑用const修饰一下?

from coost.

tigerlee avatar tigerlee commented on May 4, 2024

可是mapoperator[]()在添加之后,不会影响到其它值呀。我举的例子中,不仅v["name"]值为null了,就连v本身也变成null了。我觉得这个影响有点大。

from coost.

yanlinlin82 avatar yanlinlin82 commented on May 4, 2024

理解你的意思了,确实影响比较大。我觉得,这主要还是因为,相比std::map,json更像是个弱类型吧。

我以前也曾经实现过类似的json类,当时曾把这个问题视作一个feature,帮助快速构造复杂的json:

json j;
j["a"]["b"]["c"] = 1;  // {"a":{"b":{"c":1}}}

如今看来,这的确很容易造成误解。

或许可以参考std::variant(https://en.cppreference.com/w/cpp/utility/variant/get),在发生类型变化(如null => object)时抛出异常?

from coost.

idealvin avatar idealvin commented on May 4, 2024

https://github.com/idealvin/co/blob/110eadde2c89dffa259a161c100cd4161253441f/base/json.cc#L15

正常访问一个objectmember时,应该先调用has_member()来进行判断。但看上面函数的代码,如果直接使用[]来访问相关member,这里的逻辑似乎是打算支持这种行为?

如果不支持的话,21&22行的意义何在呢?
如果支持的话,接下来访问其它member或者调用str()就会出错了。如以下代码:

#include "co/json.h"

int main() {
  auto v = json::parse("{\"name\": \"tiger\"}");
  v["n"];
  printf("%s\n", v["name"].str().c_str());
  return 0;
}

输出结果是null

@tigerlee
上午你输入的 json 字符串有误,才会输出结果为 null。
你修正字符串后,不会输出 null,而是正常的 "tiger"。
请仔细检查下,应该不存在你描述的问题。

from coost.

tigerlee avatar tigerlee commented on May 4, 2024

不好意思,在构建最小代码时没注意检查。以下是经检查后的代码:

#include "co/json.h"

int main() {
  auto v = json::parse("[{\"1\":1,\"2\":2,\"3\":3,\"4\":4,\"5\":5,\"6\":6,\"7\":7}]");
  Json i = v[0];
  i["8"];
  printf("%s\n", i.str().c_str());
  printf("%s\n", v[0].str().c_str());
  printf("%s\n", v.str().c_str());
  return 0;
}

这个问题的特殊点在于object的属性必须为7个(更多的我没试过,估计与内存分配算法有关)。
在第7行输出i.str()时是正常的,但后面的代码就不正常了。以上代码的输出结果如下:

{"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":null}

[]

from coost.

idealvin avatar idealvin commented on May 4, 2024

不好意思,在构建最小代码时没注意检查。以下是经检查后的代码:

#include "co/json.h"

int main() {
  auto v = json::parse("[{\"1\":1,\"2\":2,\"3\":3,\"4\":4,\"5\":5,\"6\":6,\"7\":7}]");
  Json i = v[0];
  i["8"];
  printf("%s\n", i.str().c_str());
  printf("%s\n", v[0].str().c_str());
  printf("%s\n", v.str().c_str());
  return 0;
}

这个问题的特殊点在于object的属性必须为7个(更多的我没试过,估计与内存分配算法有关)。
在第7行输出i.str()时是正常的,但后面的代码就不正常了。以上代码的输出结果如下:

{"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":null}

[]

这个问题的原因是,Json i = v[0], i 和 v[0] 在内部有一个相同的指针,指向一块共享的内存,
但 i[8] 这个操作导致 i 内部重新分配了内存,v[0] 原先的那个指针失效了。

在这种情况下,建议将 Json i = v[0] 改成

Json& i = v[0];

from coost.

tigerlee avatar tigerlee commented on May 4, 2024

我在实际使用中改成了先用has_member()判断再访问。
既然有这个问题存在,而文档上并没有禁止这种做法,总感觉应该做点什么来从源头避免这个问题。 😄

from coost.

idealvin avatar idealvin commented on May 4, 2024

@tigerlee dev 分支试着修复了这个问题,可以验证下?

from coost.

tigerlee avatar tigerlee commented on May 4, 2024

验证通过,没问题了。

from coost.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.